在 TypeScript 中你可以做
const obj = {
'123-123': 1,
'456-456': 2,
}
type objKeys = keyof typeof obj
并且objKeys
是联合类型'123-123' | '456-456'
。
obj
如果不是一个对象,而是一个地图,是否有类似的可能?
const map = new Map<string, number>([
['123-123', 1],
['456-456', 2],
])
type mapKeys = ???
如果你写new Map<string, number>(...)
,那么你明确地给出了Map
一个string
键类型,这意味着它将允许你set()
和get()
字符串值的键。如果要将键限制为字符串文字类型的特定联合,则需要更改构造. 例如,如果您提前定义,则可以使用它来代替:Map
MapKeys
string
type MapKeys = '123-123' | '456-456';
const map = new Map<MapKeys, number>([
['123-123', 1],
['456-456', 2],
]);
但这有点多余,并且无论如何都与您的要求相反。您希望编译器从传递给构造函数的参数中进行推断。 MapKeys
Map
既然你说用例是为了Map
保持不变(所以不仅它的键受到约束,而且它的值也不会改变),那么TypeScript 提供的ReadonlyMap<K, V>
接口可能会更好地为你服务。在运行时没有ReadonlyMap
,但 TypeScript 编译器将允许您将Map
实例分配给 type 的变量ReadonlyMap
。
如果我们希望编译器推断MapKeys
,我们可能希望将构造函数的键类型限制string
为,这给编译器一个字符串的提示。
这两个都意味着创建新ReadonlyMap<K, V>
whereK
的辅助函数string
将有所帮助:
function ReadonlyMapWithStringKeys<K extends string, V>(
iterable: Iterable<[K, V]>): ReadonlyMap<K, V> {
return new Map(iterable)
}
const map = ReadonlyMapWithStringKeys([
['123-123', 1],
['456-456', 2],
])
// const map: ReadonlyMap<"123-123" | "456-456", number>
现在我们可以看到它map
的键是强类型的。我们现在可以MapKeys
从中定义。有多种方法可以做到这一点;一种是对关键字使用条件类型推断infer
type MapKeys = typeof map extends ReadonlyMap<infer K, any> ? K : never;
// type MapKeys = "123-123" | "456-456"
或者您可以使用类型之类的实用程序Parameters<T>
类型来询问编译器的第一个参数map.get()
是什么:
type MapKeys = Parameters<typeof map["get"]>[0]
// type MapKeys = "123-123" | "456-456"
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句