TypeScript - 如何将索引签名表示为泛型类型

时间:2017-02-10 09:25:32

标签: generics typescript generic-constraints

因此定义了TypeScript中的索引签名:

词典

[key: string]: T

阵列

[index: number]: T

这些可以包含在一些简单,可重复使用的类型中:

type DictionaryIndex<T> = {
    [key: string]: T
}

type ArrayIndex<T> = {
    [index: number]: T
}

现在我想将它们包装成单一类型。我试过这个:

type Index<TKey extends string|number, TValue> = {
    [key: TKey]: TValue
}

由于以下错误,无法编译:

  

索引签名参数的类型必须为&#39; string&#39;或者&#39;数字&#39;。

这不可能吗?

到底是为了什么?

因为

foo(obj: Index<string, Bar>)
foo(obj: Index<string, Bar> & Fooable<string>)

看起来比

更整洁
foo(obj: { [key: string]: Bar })
foo(obj: { [key: string]: Bar, canFoo: (foo: string) => Bar })

1 个答案:

答案 0 :(得分:3)

很酷的问题!
我认为原因是这对于编译器而言实际上是一个尚未实现的边缘情况可能因为它不值得努力。

索引属性键只能是明显的数字,而对象属性键只能是字符串或数字。所以最后你的约束只说明了什么是事实,以及编译器需要通过特殊情况处理什么 所以我再次假设圣安德斯放弃了这种努力; - )

但为什么不这样做

type StrIndex<TValue> = {
    [key: string]: TValue
}

type NumIndex<TValue> = {
    [key: number]: TValue
}

foo(obj: StrIndex<Bar>)
foo(obj: StrIndex<Bar> & Fooable<string>)

它不像你的解决方案那样整洁,但作为折衷方案似乎没问题,因为XXXIndex类型的集合限于2

相关问题