如何“取消索引”类型?

时间:2019-11-22 15:16:20

标签: typescript

我正试图了解如何“取消索引”。

给出:

type Example = {
    sayHi: {
        name: string;
    } | {
        sayHi: string;
    };
    cure: {
        bool: boolean;
    } | {
        cure: string;
    };
}

我如何获得:

({name: string; } | { sayHi: string; }) & ({bool: boolean } | { cure: string })

我已经尝试过了,但是将所有内容都简化为一个工会。

type Example2 = Example[keyof Example]

1 个答案:

答案 0 :(得分:3)

我们可以使用UnionToIntersection的变体形式,该变体分布在与属性值相交的类型的键上:

type Example = {
    sayHi: {
        name: string;
    } | {
        sayHi: string;
    };
    cure: {
        bool: boolean;
    } | {
        cure: string;
    };
}


type UnionToIntersectionValues<U, K extends keyof U = keyof U> = 
    (K extends unknown ? (k: U[K]) => void : never) extends ((k: infer I) => void) ? I : never

type R = UnionToIntersectionValues<Example>
// type R = ({
//     name: string;
// } & {
//     bool: boolean;
// }) | ({
//     name: string;
// } & {
//     cure: string;
// }) | ({
//     sayHi: string;
// } & {
//     bool: boolean;
// }) | ({
//     sayHi: string;
// } & {
//     cure: string;
// })

Playground Link

注意: Ts将根据(A | B) & (C | D)(A & C) | (A & D) | (B & C) | (B & D)的等价关系将交点向内移动,并将并集移至外部,因此R的类型是等效的到您要寻找的类型。