Tìm kiếm trang web

redux - rootReducer=combineReducer tạo ra kiểu 'Never' với typescript


Khi kết hợp các reducer của tôi, kiểu đang đặt root reducer thành Reducer1: never, Reducer2: never

Ví dụ :

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

export type RootState = ReturnType<typeof rootReducer>;

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

Thay vào đó, loại đang xuất ra là,

câu chuyện: không bao giờ; câu chuyện lưu trữ: không bao giờ

Tôi đã theo một gợi ý khác trên Stack Overflow và thử chỉ định loại.

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

Nhưng nó vẫn đang cố gắng ánh xạ chúng tới Never

Kiểu 'Reducer, FetchStoriesAction | AddStoriesAction | ArchiveStoryAction>' không thể gán cho kiểu 'Reducer<{ stories: IStory[]; archivedStories: number[]; }, FetchStoriesAction | AddStoriesAction | ArchiveStoryAction>'. Các kiểu của các tham số 'state' và 'prevState' không tương thích. Kiểu '{ stories: IStory[]; archivedStories: number[]; }' không thể gán cho kiểu 'CombinedState<{ stories: never; archivedStories: never; }>'. Kiểu '{ stories: IStory[]; archivedStories: number[]; }' không thể gán cho kiểu '{ stories: never; archivedStories: never; }'. Các kiểu của thuộc tính 'stories' không tương thích. Kiểu 'IStory[]' không thể gán cho kiểu 'never'.ts(2322)

Vấn đề ở đây là gì? Hoặc làm thế nào tôi có thể chỉ định kiểu một cách chính xác? Mục tiêu của tôi là sử dụng .filter trên payload IStory[].

Đây là các bộ giảm tốc:

Bộ giảm truyện

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

Bộ giảm lưu trữ

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;

Câu trả lời #1

Tôi đề xuất thực thi kiểu trả về của reducer của bạn. Đó là điều tôi thích làm, vì nó giúp kiểm tra kiểu trong việc triển khai reducer:

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

Bạn sẽ không cần phải gõ rõ ràng reducer, nó sẽ chỉ hoạt động với mã gốc của bạn:

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

export type RootState = ReturnType<typeof rootReducer>;

Đây là một sân chơi trình diễn kết quả: link

Bài viết liên quan