英文:
Typing useReducer in React with Enum type with different payload types
问题
我正在编写一个接受带有 Enum 类型 type 属性的 action 的 reducer 函数,而 action 的 payload 取决于 Enum 类型。
我知道可以使用联合类型为每个枚举类型提供不同的 payload 类型,但我有一个 action,它的 payload 类型是 Date,而所有其他 action 的 payload 类型都是 number。
我尝试过的
enum DatePickerActionType {
PICK_YEAR = 'PICK_YEAR',
PICK_MONTH = 'PICK_MONTH',
PICK_DATE = 'PICK_DATE',
PICK_HOURS = 'PICK_HOURS',
PICK_MINUTES = 'PICK_MINUTES',
}
type DatePickerAction =
| {
type: DatePickerActionType.PICK_DATE;
payload: Date;
}
| {
type: DatePickerActionType;
payload: number;
};
const datePickerReducer = (state: DatePickerValue, action: DatePickerAction): DatePickerValue => {
switch (action.type) {
case DatePickerActionType.PICK_DATE: {
const a = action.payload;
}
//...
}
};
然而,当 action 类型为 PICK_DATE 时, TypeScript 仍然显示 action.type 为 number 或 Date
是否有方法可以为除了枚举类型以外的所有 action 定义 payload 类型为 number,还是我应该使用联合类型分别定义所有 action?
type DatePickerAction =
| {
type: DatePickerActionType.PICK_DATE;
payload: Date;
}
| {
type: DatePickerActionType.PICK_HOURS;
payload: number;
}
| {
type: DatePickerActionType.PICK_MINUTES;
payload: number;
}
| {
/**... */
};
(注意:代码部分没有翻译,只提供翻译好的文本。)
英文:
I am writing reducer function which accepts action with type property whos type is Enum type and action payload depends on Enum type.
I know that I can provide different payload types for each enum type using union types, but I have one action which payload is Date and all other actions have payload type of number.
What I've tried
enum DatePickerActionType {
PICK_YEAR = 'PICK_YEAR',
PICK_MONTH = 'PICK_MONTH',
PICK_DATE = 'PICK_DATE',
PICK_HOURS = 'PICK_HOURS',
PICK_MINUTES = 'PICK_MINUTES',
}
type DatePickerAction =
| {
type: DatePickerActionType.PICK_DATE;
payload: Date;
}
| {
type: DatePickerActionType;
payload: number;
};
const datePickerReducer = (state: DatePickerValue, action: DatePickerAction): DatePickerValue => {
switch (action.type) {
case DatePickerActionType.PICK_DATE: {
const a = action.payload;
}
//...
}
};
However typescript still shows me action.type as number or Date when action type is PICK_DATE
Is there way to define payload type as number for all actions except on enum type or I should go with union type defining all actions separately?
type DatePickerAction =
| {
type: DatePickerActionType.PICK_DATE;
payload: Date;
}
| {
type: DatePickerActionType.PICK_HOURS;
payload: number;
}
| {
type: DatePickerActionType.PICK_MINUTES;
payload: number;
}
| {
/**... */
};
答案1
得分: 1
尝试使用Exclude
来排除特定的枚举:
// ...
type DatePickerAction =
| {
type: DatePickerActionType.PICK_DATE;
payload: Date;
}
| {
type: Exclude<DatePickerActionType, DatePickerActionType.PICK_DATE>;
payload: number;
};
const datePickerReducer = (state: DatePickerValue, action: DatePickerAction): DatePickerValue => {
switch (action.type) {
case DatePickerActionType.PICK_DATE: {
const a = action.payload; // 日期(Date)
break;
}
default: {
const a = action.payload; // 数字(number)
}
//...
}
};
英文:
Try Exclude
the specific enum:
// ...
type DatePickerAction =
| {
type: DatePickerActionType.PICK_DATE;
payload: Date;
}
| {
type: Exclude<DatePickerActionType, DatePickerActionType.PICK_DATE>;
payload: number;
};
const datePickerReducer = (state: DatePickerValue, action: DatePickerAction): DatePickerValue => {
switch (action.type) {
case DatePickerActionType.PICK_DATE: {
const a = action.payload; // Date
break;
}
default: {
const a = action.payload; // number
}
//...
}
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论