Пытаюсь эксперементировать с typescript и react. У меня есть разные GameEventType, что то вроде
export interface GameEvent {
id: number;
eventName: string;
}
export interface NewGemsEvent extends GameEvent {
gems: Gem[];
eventName: "NewGemsEvent";
}
export interface CollapseEvent extends GameEvent {
eventName: "CollapseEvent";
}
export type GameEventType = CollapseEvent | NewGemsEvent;
Есть игровое поле field: Gem[]. Хочу получая разные GameEventType обновлять игровое поле.
Для этого создал такую функцию reducer
function fieldReducer(field: Gem[], event: GameEventType) : Gem[] {
switch (event.eventName) {
case "NewGemsEvent":
return [...field, ...event.gems];
default:
return field;
}
}
А это использование
const [field, updateField] = useReducer(fieldReducer, [] as Gem[], () => []);
Однако почему то useReducer не принимает эту функцию как параметр.
Argument type (field: Gem[], event: GameEventType) => Gem[] is not assignable to parameter type ReducerWithoutAction
Да и вообще useReducer почему то требует третий параметр - "initializer", хотя вроде бы третий параметр опциональный. Что то где то делаю не так, но не пойму что.
Update
Я как понимаю, почему то компайлер выбирает вариант useReducer без экшенов
function useReducer<R extends ReducerWithoutAction<any>, I>(
reducer: R,
initializerArg: I,
initializer: (arg: I) => ReducerStateWithoutAction<R>,
): [ReducerStateWithoutAction<R>, DispatchWithoutAction];
А я ожидал, что будет подтянут этот вариант
function useReducer<R extends Reducer<any, any>>(
reducer: R,
initialState: ReducerState<R>,
initializer?: undefined,
): [ReducerState<R>, Dispatch<ReducerAction<R>>];
UPDATE 2:
Добавил каст
fieldReducer as Reducer<any, any>
И мой редюсер заработал. Но все равно не пойму, как сделать правильно.