首页 > 解决方案 > rootReducer = combineReducer 使用 typescript 生成类型“Never”

问题描述

组合我的减速器时,类型将根减速器设置为减速器1:从不,减速器2:从不

例子:

const rootReducer = combineReducers({
  stories: storyReducer,
  archivedStories: archiveReducer,
});

export type RootState = ReturnType<typeof rootReducer>;

storyReducer (IStory[] , StoryActionTypes)
archiveReducer (number[], ArchiveActionTypes)

类型改为出现,

故事:从不;归档故事:从不

我遵循了另一个堆栈溢出建议并尝试指定类型。

const rootReducer: Reducer<CombinedState<{stories: IStory[]; archivedStories: number[];}>, StoryActionTypes | ArchiveActionTypes> = combineReducers({
  stories: storyReducer,
  archivedStories: archiveReducer,
});

但它仍在尝试将它们映射到从不

输入 'Reducer<CombinedState<{ 故事:从不;归档故事:从不;}>, FetchStoriesAction | 添加故事动作 | ArchiveStoryAction>' 不可分配给类型 'Reducer<{ stories: IStory[]; 归档故事:数字[];}, FetchStoriesAction | 添加故事动作 | 存档故事动作>'。参数 'state' 和 'prevState' 的类型不兼容。类型 '{ 故事:IStory[]; 归档故事:数字[];}' 不可分配给类型 'CombinedState<{ stories: never; 归档故事:从不;}>'。类型 '{ 故事:IStory[]; 归档故事:数字[];}' 不能分配给类型 '{ stories: never; 归档故事:从不;}'。属性“故事”的类型不兼容。类型 'IStory[]' 不可分配给类型 'never'.ts(2322)

这里有什么问题?或者如何正确指定类型?我的目标是在 IStory[] 有效负载上使用 .filter。

这些是减速器:

故事还原器

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;
  }
};

存档缩减器

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;

标签: typescriptredux

解决方案


我建议强制执行减速器的返回类型。这是我喜欢做的事情,因为它有助于对 reducer 实现进行类型检查:

//                                                           here
//                                                              v
function storyReducer(state: IStory[], action: StoryActionTypes): IStory[] {
  // ...
}

您无需显式键入 reducer,它只适用于您的原始代码:

const rootReducer = combineReducers({
  stories: storyReducer,
  archivedStories: archiveReducer,
});

export type RootState = ReturnType<typeof rootReducer>;

这是一个展示结果的游乐场:链接


推荐阅读