【问题标题】:How can I get tuple type from the members of another type in typescript?如何从打字稿中另一种类型的成员中获取元组类型?
【发布时间】:2021-10-27 04:24:44
【问题描述】:

假设我有这样的类型,有几个成员:

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?

【问题讨论】:

    标签: typescript


    【解决方案1】:
    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]
    

    Playground

    关于将 union 转换为 array 可以找到更多解释here

    因为这个答案是已经存在的解决方案的混合,你可以在我留在每个帮助者上方的适当链接中找到更多解释

    【讨论】:

    • 对于UnionToIntersection,这是否意味着:当联合分配给函数时,它会产生另一个仅包含联合交集的一个参数类型的单个函数?
    • @jayatubi UnionToIntersection 只是将联合转换为交集。例如:{a:1} | {b: 1}{a:1,b:1} 请参阅此链接 stackoverflow.com/a/50375286 了解更多信息
    • 这个答案很完美。我花了几个小时来理解答案的每一行。有很多新知识让我学习。非常感谢!
    • 不幸的是,这不是微不足道的。每次了解这些实用程序所需的时间都会越来越少
    猜你喜欢
    • 2022-10-12
    • 2021-04-18
    • 2021-03-13
    • 1970-01-01
    • 2022-09-29
    • 2020-05-09
    • 2021-04-24
    • 2017-11-02
    • 2021-12-30
    相关资源
    最近更新 更多