如何将映射的泛型转换成打字稿中的元组并集

时间:2019-06-28 17:58:21

标签: typescript templates generics

我正在创建类似于Object.entries的东西,我希望它被更强地键入。我要创建一个给定对象返回该对象属性的2元组的强类型联合的类型。

当前

export type Entries<T> = [keyof T, T[keyof T]][];

Entries<{first: number, second: string}> = ["first" | "second", number | string][]

我想要的东西

Entries<{first: number, second: string}> = ["first", number] | ["second", string][]

1 个答案:

答案 0 :(得分:2)

您应该使用具有{[K in keyof T]: ...}语法的实际mapped type,然后look up使用其属性:

export type Entries<T> = { [K in keyof T]: [K, T[K]] }[keyof T][];

type E = Entries<{ first: number; second: string }>;
// type E = (["first", number] | ["second", string])[]

您还可以使用类似distributive conditional typeinference in conditional types,它需要一个辅助类型别名才能工作:

type EntriesHelper<T, K> = K extends keyof T ? [K, T[K]] : never;
type Entries<T> = Array<EntriesHelper<T, keyof T>>;

type E = Entries<{ first: number; second: string }>;
// type E = (["first", number] | ["second", string])

或者像这样使用Link to code代替助手的人:

type Entries<T> = Array<
  keyof T extends infer K ? (K extends keyof T ? [K, T[K]] : never) : never
>;

type E = Entries<{ first: number; second: string }>;
// type E = (["first", number] | ["second", string])[]

它们在这里都产生相同的输出,但是在遇到可选属性或其他边缘情况时,它们的行为可能有所不同,因此请小心。希望能有所帮助;祝你好运!

{{3}}