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

tom*_*271 3 types constants custom-type typescript typescript-typings

这是无法编译的

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

export type QuantityMode = QuantityModes.POSITIVE | QuantityModes.NEGATIVE | QuantityModes.ANY;
Run Code Online (Sandbox Code Playgroud)

这是可以编译的

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

export type QuantityMode = 'POSITIVE' | 'NEGATIVE' | 'ANY';
Run Code Online (Sandbox Code Playgroud)

Tit*_*mir 6

您遇到的第一个问题是属性的类型实际上都不string是您可能期望的字符串文字类型。为了解决这个问题,我们可以使用类型断言:

export const QuantityModes = {
    POSITIVE: 'POSITIVE' as 'POSITIVE', 
    NEGATIVE: 'NEGATIVE' as 'NEGATIVE',
    ANY: 'ANY' as 'ANY', 
};
Run Code Online (Sandbox Code Playgroud)

使用辅助函数向编译器提示我们需要类型文字:

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

或者,从 3.4(尚未发布)开始,您可以编写as const

export const QuantityModes = {
    POSITIVE: 'POSITIVE', 
    NEGATIVE: 'NEGATIVE',
    ANY: 'ANY', 
} as const
Run Code Online (Sandbox Code Playgroud)

您可以键入相对于另一种类型的类型,但语法不同。首先,如果您想访问属性的类型,语法是type['propName'](也称为索引类型查询)。但是您想要访问常量的类型,为此您需要使用typeof const. 所以你可以写:

export type QuantityMode = typeof QuantityModes["POSITIVE"] | typeof QuantityModes["NEGATIVE"] | typeof QuantityModes["ANY"];
Run Code Online (Sandbox Code Playgroud)

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

export type QuantityMode = typeof QuantityModes["POSITIVE" | "NEGATIVE" | "ANY"];
Run Code Online (Sandbox Code Playgroud)

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

export type QuantityMode = typeof QuantityModes[keyof typeof QuantityModes];
Run Code Online (Sandbox Code Playgroud)

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

export type QuantityMode = keyof typeof QuantityModes;
Run Code Online (Sandbox Code Playgroud)