我有这个界面:
interface SocketServerEvents {
complete : (data :string)=>void;
response : (data :number)=>void;
error : (error:string)=>void;
}
我想将其转换为与以下内容匹配的类型:
[
[ "complete", (data :string)=>void ],
[ "response", (data :number)=>void ],
[ "error", (data :number)=>void ]
]
重点是该数组是元组数组,其中:
[ keyof SocketServer Events, valueOfThatKey SocketServerEvents ]
这可以在 TypeScript 中完成吗?
您要找的类型是
type SocketServerEventsEntryArray = Array<
["complete", (data: string) => void] |
["response", (data: number) => void] |
["error", (error: string) => void]
>;
您可以让 TypeScript 根据
SocketServerEnvents
为您计算,如下所示:
type Entry<T> = { [K in keyof T]: [K, T[K]] }[keyof T];
type EntryArray<T> = Array<Entry<T>>;
Entry<T>
实用程序类型是在microsoft/TypeScript#47109中创造的分布式对象类型。分布式对象类型是一种映射类型,您可以立即对其进行索引以获得联合结果。 type G<K extends PropertyKey> = {[P in K]: F<P>}[K]
形式的类型将导致 G<K1 | K2 | K3>
分布在其参数中的并集上以生成 F<K1> | F<K2> | F<K3>
。 所以 [K, T[K]]
是您关心的特定键 K
的 tuple,并且
Entry<T>
将其分布在 keyof T
中键的并集上。 然后我们只需将 Array<T>
包裹起来,这自然会让您能够重复或丢失元素。
所以你可以写
type SocketServerEventsEntryArray = EntryArray<SocketServerEvents>;
你就完成了。
请注意,microsoft/TypeScript#55632 存在一个突出的错误,阻止像Entry<SocketServerEvents>
这样的元组类型的
有区别的联合具有正确的 IntelliSense 或根据上下文推断回调的参数类型。 这意味着您必须更加努力地创建这种类型的值(如果您将
[K, T[K]]
更改为像 {k: K, v: T[K]}
这样的对象,这种情况就会消失),但它仍然是所提出问题的正确类型。