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

时间:2019-02-12 06:27:57

标签: typescript types constants typescript-typings custom-type

这是不可编译的

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 个答案:

答案 0 :(得分:4)

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

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

使用辅助函数来提示我们要输入文字的编译器:

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"];

您也可以使用并集来简化结果,

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;

答案 1 :(得分:1)

您是否考虑过使用字符串枚举?它既是类型(用于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