代码之家  ›  专栏  ›  技术社区  ›  tom10271

为什么不能在自定义类型定义中使用常量中的值?

  •  2
  • tom10271  · 技术社区  · 5 年前

    这是不可编译的

    export const QuantityModes = {
        POSITIVE: 'POSITIVE', 
        NEGATIVE: 'NEGATIVE',
        ANY: 'ANY', 
    };
    
    export type QuantityMode = QuantityModes.POSITIVE | QuantityModes.NEGATIVE | QuantityModes.ANY;
    

    这是可编译的

    export const QuantityModes = {
        POSITIVE: 'POSITIVE',
        NEGATIVE: 'NEGATIVE',
        ANY: 'ANY',
    };
    
    export type QuantityMode = 'POSITIVE' | 'NEGATIVE' | 'ANY';
    
    2 回复  |  直到 5 年前
        1
  •  4
  •   Titian Cernicova-Dragomir    5 年前

    第一个问题是,属性的类型实际上是 string 不是您期望的字符串文本类型。要解决此问题,我们可以使用类型断言:

    export const QuantityModes = {
        POSITIVE: 'POSITIVE' as 'POSITIVE', 
        NEGATIVE: 'NEGATIVE' as 'NEGATIVE',
        ANY: 'ANY' as 'ANY', 
    };
    

    使用helper函数提示编译器我们需要类型文本:

    export const QuantityModes = (<T extends { [P in keyof T]: P }>(o: T)=> o)({
        POSITIVE: 'POSITIVE', 
        NEGATIVE: 'NEGATIVE',
        ANY: 'ANY', 
    })
    

    或者,从3.4开始(尚未解除),您可以编写 as const :

    export const QuantityModes = {
        POSITIVE: 'POSITIVE', 
        NEGATIVE: 'NEGATIVE',
        ANY: 'ANY', 
    } as const
    

    您可以键入与其他类型相关的类型,但语法不同。首先,如果要访问属性的类型,语法是 type['propName'] (也称为 index type query )但要访问常量的类型,需要使用 typeof const . 所以你可以写:

    export type QuantityMode = typeof QuantityModes["POSITIVE"] | typeof QuantityModes["NEGATIVE"] | typeof QuantityModes["ANY"];
    

    您还可以使用union简化一点,得到相同的结果:

    export type QuantityMode = typeof QuantityModes["POSITIVE" | "NEGATIVE" | "ANY"];
    

    如果联合包含所有属性名,那么我们只能使用 keyof type 获取类型中所有属性名的联合(确保将来添加的所有属性名也自动添加到类型中)

    export type QuantityMode = typeof QuantityModes[keyof typeof QuantityModes];
    

    因为在这种情况下,属性名和属性类型是相同的,我们甚至可以使用 keyof :

    export type QuantityMode = keyof typeof QuantityModes;
    
        2
  •  1
  •   Romain Deneau    5 年前

    是否考虑改用字符串枚举?它既是一个类型(用于typescript编译器)又是一个值(javascript伪映射对象,相当于 const QuantityModes )还有一些限制,但更方便。

    enum QuantityMode {
        POSITIVE = 'POSITIVE', 
        NEGATIVE = 'NEGATIVE',
        ANY = 'ANY', 
    }
    
    const a_ko: QuantityMode = 'POSITIVE';     // Error: Type '"POSITIVE"' is not assignable to type 'QuantityMode'
    const a_ok_1 = QuantityMode.POSITIVE;      // Strict use
    const a_ok_2 = 'POSITIVE' as QuantityMode; // Lax use
    
    // Composable within an union type
    type QuantityStrictMode = QuantityMode.POSITIVE | QuantityMode.NEGATIVE;
    
    const b_ko  : QuantityStrictMode = 'POSITIVE';            // Error: Type '"POSITIVE"' is not assignable to type 'QuantityStrictMode'
    const b_ok_1: QuantityStrictMode = QuantityMode.POSITIVE; // Strict use
    const b_ok_2 = 'POSITIVE' as QuantityStrictMode;          // Lax use