将接口转换为[接口键,接口值][]的数组元组类型

问题描述 投票:0回答:1

我有这个界面:

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 中完成吗?

typescript
1个回答
0
投票

您要找的类型是

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]}
这样的对象,这种情况就会消失),但它仍然是所提出问题的正确类型。

Playground 代码链接

© www.soinside.com 2019 - 2024. All rights reserved.