为什么我不能使用常量中的值作为自定义类型定义?
Why cannot I use value in constant as custom type definition?
这是不可编译的
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';
您遇到的第一个问题是属性的类型实际上都是 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"];
你也可以使用 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;
您是否考虑过改用字符串枚举?它既是一个类型(对于 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
这是不可编译的
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';
您遇到的第一个问题是属性的类型实际上都是 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"];
你也可以使用 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;
您是否考虑过改用字符串枚举?它既是一个类型(对于 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