如何在types
中引用常量?例如,我有一些常量值,如A和B,需要创建一个Action Type,以便我可以在switch case
中使用Action类型
const PATH = '@@test/';
export const A = `${PATH}A`;
export const B = `${PATH}B`;
export type Action =
// UI actions
{ type: typeof A, payload: { a: any } }
| { type: B, payload: { b: boolean }}
//用法
const id = (state= initialState, action: Action) => {
const nextState = state;
switch (action.type) {
case A: {
const{a} = action.payload;
break;
}
case B: {
const { b} = action.payload;
break;
}
default:
break;
}
答案 0 :(得分:0)
TypeScript(截至v2.5)缺乏concatenate string literal types的能力。在TypeScript中连接两个字符串文字时,结果类型只知道为string
。例如,它不知道以下是正确的:
const x = "x";
const xx: "xx" = x + x; // error!
在您的情况下,TypeScript会将A
和B
推断为string
值:
export const A = `${PATH}A`; // inferred as string
export const B = `${PATH}B`; // inferred as string
因此,Action
不被视为discriminated union,因为type
属性在两种情况下均相同:
export type Action =
{ type: typeof A, payload: { a: any } } |
{ type: typeof B, payload: { b: boolean } }
这是您手动指定A
和B
的文字类型的唯一方法,可能需要运行时检查以确保您没有错误配置常量。是的,那是unfortunate,但它有效:
const PATH = '@@test/';
export const A = "@@test/A";
export const B = "@@test/B";
if (!A.startsWith(PATH) || !B.startsWith(PATH)) {
throw new Error("Bad configuration");
}
现在,Action
是一个适当的歧视联盟,当你在switch
属性上type
时,TypeScript会自动缩小类型:
declare const action: Action;
switch (action.type) {
case A: {
const { a } = action.payload; // okay
break;
}
case B: {
const { b } = action.payload; // okay
break;
}
default:
const assertNever: never = action; // okay
break;
}
希望有所帮助;祝你好运!