typescript - 如何从打字稿中另一种类型的成员中获取元组类型?
问题描述
假设我有这样的类型,有几个成员:
type TheType = {
PK_1: number;
PK_2: number; // The type may same as other
PK_3: boolean;
PK_4: string;
}
我想得到一个类型的元组,其中包含上面每个成员的每种类型,例如:
// Should return as [number, number, boolean, string]
type TypeTuple = ToTuple<TheType>; // How to make this ToTuple method?
解决方案
type TheType = {
PK_1: number;
PK_2: number; // The type may same as other
PK_3: boolean;
PK_4: string;
}
// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
k: infer I
) => void
? I
: never;
// credits goes to https://github.com/microsoft/TypeScript/issues/13298#issuecomment-468114901
type UnionToOvlds<U> = UnionToIntersection<
U extends any ? (f: U) => void : never
>;
type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never;
// credit goes to https://stackoverflow.com/questions/53953814/typescript-check-if-a-type-is-a-union#comment-94748994
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;
type UnionToArray<T, A extends unknown[] = []> = IsUnion<T> extends true
? UnionToArray<Exclude<T, PopUnion<T>>, [PopUnion<T>, ...A]>
: [T, ...A];
type MapPredicate<Obj, Key> = Key extends keyof Obj ? Obj[Key] : never
// credit goes to https://catchts.com/tuples#map
type Mapped<
Obj,
Arr extends Array<unknown>,
Result extends Array<unknown> = [],
> = Arr extends []
? []
: Arr extends [infer H]
? [...Result, MapPredicate<Obj, H>]
: Arr extends [infer Head, ...infer Tail]
? Mapped<Obj, [...Tail], [...Result, MapPredicate<Obj, Head>]>
: Readonly<Result>;
type Result = Mapped<TheType, UnionToArray<keyof TheType>>; // [number, number, boolean, string]
关于将联合转换为数组,您可以在此处找到更多解释
因为这个答案是现有解决方案的混合,您可以在我留在每个助手上方的适当链接中找到更多解释