redux - rootReducer=combineReducer produce tipul 'Never' cu typescript
Când combin reducerii mei, tipul setează reducerul rădăcină la Reducer1: niciodată, Reducer2: niciodată
Exemplu :
const rootReducer = combineReducers({
stories: storyReducer,
archivedStories: archiveReducer,
});
export type RootState = ReturnType<typeof rootReducer>;
storyReducer (IStory[] , StoryActionTypes)
archiveReducer (number[], ArchiveActionTypes)
Tipul iese în schimb ca,
povești: niciodată; poveștiArhivate: niciodată
Am urmat o altă sugestie de pe Stack Overflow și am încercat să specific tipul.
const rootReducer: Reducer<CombinedState<{stories: IStory[]; archivedStories: number[];}>, StoryActionTypes | ArchiveActionTypes> = combineReducers({
stories: storyReducer,
archivedStories: archiveReducer,
});
Dar încă încearcă să le map-eze la Never
Tipul 'Reducer<CombinedState<{ stories: never; archivedStories: never; }>, FetchStoriesAction | AddStoriesAction | ArchiveStoryAction>' nu poate fi atribuit tipului 'Reducer<{ stories: IStory[]; archivedStories: number[]; }, FetchStoriesAction | AddStoriesAction | ArchiveStoryAction>'. Tipurile de parametri 'state' și 'prevState' sunt incompatibile. Tipul '{ stories: IStory[]; archivedStories: number[]; }' nu poate fi atribuit tipului 'CombinedState<{ stories: never; archivedStories: never; }>'. Tipul '{ stories: IStory[]; archivedStories: number[]; }' nu poate fi atribuit tipului '{ stories: never; archivedStories: never; }'. Tipurile proprietății 'stories' sunt incompatibile. Tipul 'IStory[]' nu poate fi atribuit tipului 'never'.ts(2322)
Care este problema aici? Sau cum pot să specific corect tipul? Scopul meu este să folosesc .filter pe payload-ul IStory[] .
Acestea sunt reductoarele:
Reductor de povești
const INITIAL_STATE: IStory[] = []
const applyAddStories = (state: IStory[], action: StoryActionTypes) => action.payload;
export const storyReducer = (
state = INITIAL_STATE,
action: StoryActionTypes
) => {
switch (action.type) {
case STORIES_ADD : {
return applyAddStories(state, action)
}
default:
return state;
}
};
Reducer de arhivă
const INITIAL_STATE: number[] = []
const applyArchiveStory = (state: number[], action: ArchiveActionTypes) => [
...state,
action.payload,
];
export const archiveReducer = (
state = INITIAL_STATE,
action: ArchiveActionTypes
) => {
switch (action.type) {
case STORY_ARCHIVE: {
return applyArchiveStory(state, action);
}
default:
return state;
}
};
export default archiveReducer;
Răspuns #1
Aș recomanda să impui tipul de returnare al reducer-ului tău. Este ceva ce îmi place să fac, deoarece ajută la verificarea tipurilor în implementarea reducer-ului:
// here
// v
function storyReducer(state: IStory[], action: StoryActionTypes): IStory[] {
// ...
}
Nu va trebui să tastezi explicit reducerul, va funcționa pur și simplu cu codul tău original:
const rootReducer = combineReducers({
stories: storyReducer,
archivedStories: archiveReducer,
});
export type RootState = ReturnType<typeof rootReducer>;
Iată un teren de joacă care demonstrează rezultatul: link
