【问题标题】:TypeScript: Map union type to another union typeTypeScript:将联合类型映射到另一个联合类型
【发布时间】:2019-01-12 10:41:46
【问题描述】:

是否可以在 TypeScript 中将联合类型映射到另一个联合类型?

我想做的事

例如给定一个联合类型 A:

type A = 'one' | 'two' | 'three';

我希望能够将其映射到联合类型 B:

type B = { type: 'one' } | { type: 'two'} | { type: 'three' };

我的尝试

type B = { type: A };

但这会导致:

type B = { type: 'one' | 'two' | 'three' };

这不是我想要的。

【问题讨论】:

    标签: typescript discriminated-union


    【解决方案1】:

    distributing over the members of the union type 可以使用条件类型(条件类型总是只占用一个分支并且仅用于它的分配属性,我 这个方法是从this answer学来的)

    type A = 'one' | 'two' | 'three';
    
    type Distribute<U> = U extends any ? {type: U} : never;
    
    type B = Distribute<A>;
    
    /*
    type B = {
        type: "one";
    } | {
        type: "two";
    } | {
        type: "three";
    }
    */
    

    【讨论】:

    • 这行得通。出于好奇,U extends {} 如何解决提供 { type: U } 的真实性?
    • U extends {} 适用于对象类型、stringnumberboolean 等“值”类型以及这些值类型的文字。如果Uundefinedvoid 则为假,因此“总是只取一个分支”的说法不正确,U extends {}voidundefined 从联合中排除。我更新了答案以将其更改为 U extends any,因为我不知道是否真的需要排除 voidundefined 之类的类型。
    • 感谢您的澄清。我很惊讶字符串文字扩展了 {}
    • {} 描述了一个没有属性的类型,因此除了undefinednull 之外的每个值都与该描述匹配(它们是“没有属性的对象”的超集)。跨度>
    • 好的,这就行了:type PickFieldTypes&lt;U, K extends keyof U&gt; = U extends any ? U[K] : never;。太好了!!
    猜你喜欢
    • 2021-01-26
    • 2019-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 2021-10-27
    • 1970-01-01
    • 2020-02-25
    相关资源
    最近更新 更多