在 TypeScript 中你可以这样做
const obj = {
'123-123': 1,
'456-456': 2,
}
type objKeys = keyof typeof obj
Run Code Online (Sandbox Code Playgroud)
并且objKeys是联合型'123-123' | '456-456'。
obj如果不是对象而是地图,是否可能有类似的情况?
const map = new Map<string, number>([
['123-123', 1],
['456-456', 2],
])
type mapKeys = ???
Run Code Online (Sandbox Code Playgroud)
如果你new Map<string, number>(...)这样写,那么你就明确地给出了Map一个string键类型,这意味着它将允许你set()和get()字符串值键。如果您想将键限制为字符串文字类型的特定联合,那么您将需要更改构造. 例如,如果您提前定义,则可以使用它来代替:MapMapKeysstring
type MapKeys = '123-123' | '456-456';
const map = new Map<MapKeys, number>([
['123-123', 1],
['456-456', 2],
]);
Run Code Online (Sandbox Code Playgroud)
但这有点多余,并且与您所要求的相反。您希望编译器根据传递给构造函数的参数进行推断 。MapKeysMap
既然您说用例是Map恒定的(因此不仅它的键受到限制,而且它的值也不会改变),那么TypeScript 提供的接口可能会更好ReadonlyMap<K, V>地为您服务。运行时没有ReadonlyMap,但 TypeScript 编译器将允许您将实例分配Map给 类型的变量ReadonlyMap。
如果我们希望编译器推断MapKeys,我们可能希望将构造函数的键类型限制string为,这会给编译器一个字符串提示。
ReadonlyMap<K, V>这两者都意味着创建新的K限制的辅助函数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>
Run Code Online (Sandbox Code Playgroud)
现在我们可以看到map它的键是强类型的。我们现在可以MapKeys从中定义。有多种方法可以做到这一点;一种是使用关键字条件类型推断infer
type MapKeys = typeof map extends ReadonlyMap<infer K, any> ? K : never;
// type MapKeys = "123-123" | "456-456"
Run Code Online (Sandbox Code Playgroud)
或者您可以使用实用程序类型(例如type Parameters<T>)来询问编译器的第一个参数map.get()是什么:
type MapKeys = Parameters<typeof map["get"]>[0]
// type MapKeys = "123-123" | "456-456"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2375 次 |
| 最近记录: |