Я задал вопрос ранее сегодня , основываясь на моих попытках создать отображение между redux-action-типами и редукторами для обработки каждого из этих типов, с требованием, чтобы каждый тип действия обрабатывался явно.
Я получил отличный ответ о том, как это сделать, и теперь я могу создать такое отображение, но я получаю сообщение об ошибке, когда пытаюсь использовать его для создания редуктора.
Если у меня есть следующий код (извините, он довольно длинный, но я считаю, что это минимальный пример):
export type IActionReducerMapping<S, A extends IReduxAction<string>> = {
[K in A['type']]: IReducer<S, Extract<A, { type: K }>>
};
interface IUser {
id: number;
name: string;
age: number;
}
interface IUserState {
[id: number]: IUser;
}
interface IAddUserAction {
type: 'ADD_USER';
payload: IUser;
}
interface ISetUserNameAction {
type: 'SET_USER_NAME';
payload: {
id: IUser['id'];
name: IUser['name'];
}
}
type UserAction = IAddUserAction | ISetUserNameAction;
const mapping: IActionReducerMapping<IUserState, UserAction> = {
'ADD_USER': (state, action) => ({
...state,
[action.payload.id]: action.payload,
}),
'SET_USER_NAME': (state, action) => ({
...state,
[action.payload.id]: {
...state[action.payload.id],
name: action.payload.name,
}
}),
};
const userReducer = (state: IUserState, action: UserAction) => mapping[action.type](state, action);
Я получаю следующую ошибку:
Аргумент типа «UserAction» не может быть назначен параметру типа «IAddUserAction & ISetUserNameAction». Тип «IAddUserAction» не может быть назначен типу «IAddUserAction & ISetUserNameAction». Тип «IAddUserAction» нельзя назначить типу «ISetUserNameAction». Типы свойства 'type' несовместимы. Тип "ADD_USER" не может быть назначен типу "SET_USER_NAME". Ts (2345)
Я не могу видеть, где я ошибаюсь при наборе этих символов, может кто-нибудь указать где я ошибся?
Вот ссылка на игровую площадку.
Редактировать:
Следующие работы:
const userReducer = (state: IUserState, action: ISetUserNameAction | IAddUserAction) => {
switch (action.type) {
case 'ADD_USER':
return mapping[action.type](state, action);
case 'SET_USER_NAME':
return mapping[action.type](state, action);
}
}
Предположительно, потому что на этом этапе компилятор уверен, что он может знать, что тип действия и редуктор будут прекрасно работать вместе. До сих пор остается загадкой, как я могу сделать это автоматически.