[英]TypeScript Narrow Enum Type without Casting (Redux)
我想更有效地输入我的 redux 操作。 目前,我在类Actions
声明我的Actions
并明确缩小操作类型的范围。 这样打字稿将缩小减速器中action
的类型,我可以在那里看到哪种类型的action.payload
哪个好。
但我想摆脱显式转换<ActionTypes.INCREMENT_BY_ONE>ActionTypes.INCREMENT_BY_ONE
。 它可以做得更通用/更容易/更短吗?
export enum ActionTypes {
INCREMENT_BY_ONE = 'INCREMENT_BY_ONE',
INCREMENT_BY_MULTIPLE = 'INCREMENT_BY_MULTIPLE',
}
class Actions {
incrementByOne() {
return {
type: <ActionTypes.INCREMENT_BY_ONE>ActionTypes.INCREMENT_BY_ONE,
};
}
incrementByMultiple(multiple: number) {
return {
type: <ActionTypes.INCREMENT_BY_MULTIPLE>ActionTypes.INCREMENT_BY_MULTIPLE,
payload: multiple,
};
}
}
type ValueOf<T> = T[keyof T];
export type KnownAction = ReturnType<ValueOf<Actions>>;
function reducer(state, action: KnownAction) {
switch(action.type) {
case ActionTypes.INCREMENT_BY_ONE:
// Property 'payload' does not exist on type { type ActionTypes.INCREMENT_BY_ONE; }.
const a = action.payload;
break;
case ActionTypes.INCREMENT_BY_MULTIPLE:
// payload: number
const b = action.payload;
break;
}
}
你必须告诉 TypeScript 尽可能缩小类型。 您只能明确地执行此操作 - 但是有一种很好的方法可以告诉 TypeScript 执行此操作。
class Actions {
incrementByOne() {
return {
// Typecast using const, this tells TypeScript to narrow down the type to the most specific one, which is ActionTypes.INCREMENT_BY_ONE
type: <const>ActionTypes.INCREMENT_BY_ONE,
};
}
incrementByMultiple(multiple: number) {
return {
type: ActionTypes.INCREMENT_BY_MULTIPLE as const, // Alternatively using 'as' syntax
payload: multiple,
};
}
}
或者,您可以将整个 Action 标记为 const - 好处是所有属性也将标记为只读。 这是你通常想要的 Action。
class Actions {
incrementByOne() {
return <const> {
type: ActionTypes.INCREMENT_BY_ONE,
};
}
incrementByMultiple(multiple: number) {
return {
type: ActionTypes.INCREMENT_BY_MULTIPLE,
payload: multiple,
} as const; // Alternatively using 'as' syntax
}
}
这里是Stackblitz。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.