TypeScript - 如何将索引签名表示为泛型类型
Posted
技术标签:
【中文标题】TypeScript - 如何将索引签名表示为泛型类型【英文标题】:TypeScript - How to represent an index signature as a generic type 【发布时间】:2017-02-10 09:25:32 【问题描述】: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
由于以下错误,无法编译:
索引签名参数必须是“字符串”或“数字”类型。
这不可能吗?
到底是为了什么?
因为
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 )
【问题讨论】:
TypeScript repo 上有一个关于此的问题:github.com/Microsoft/TypeScript/issues/13398 Guess it is not possible. 【参考方案1】:很酷的问题! 我认为原因是这对于尚未实现的编译器来说确实是一个边缘案例,可能是因为它不值得付出努力。
索引属性键只能是明显的数字,对象属性键只能是字符串或数字。所以最后你的约束只说明什么是事实,以及编译器需要通过特殊情况处理什么。 所以我再次假设圣安德斯放弃了这一努力;-)
但为什么不这样做
type StrIndex<TValue> =
[key: string]: TValue
type NumIndex<TValue> =
[key: number]: TValue
foo(obj: StrIndex<Bar>)
foo(obj: StrIndex<Bar> & Fooable<string>)
它不像您的解决方案那样简洁,但作为一种折衷方案,它似乎还可以,因为 XXXIndex 类型的集合限制为 2 个
【讨论】:
【参考方案2】:另一种解决方案是使用Record
实用程序。
foo(obj: Record<string, Bar>)
https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type
【讨论】:
以上是关于TypeScript - 如何将索引签名表示为泛型类型的主要内容,如果未能解决你的问题,请参考以下文章