Как правильно типизировать actions в редьюсере?

введите сюда описание изображенияПытаюсь разобраться с TS. Но что-то сложная задача для меня((. Помогите пожалуйста.

Редьюсер:

import { MoviesActionTypes, MoviesState, SearchAction } from '../types/movies';

const initialState: MoviesState = {
  movies: [],
};

export function moviesReducer(state = initialState, action: SearchAction): MoviesState {
  return action.type === MoviesActionTypes.SEARCH
    ? { ...state, movies: [...action.payload.films] }
    : state;
}

Типы

export interface MoviesState {
  movies: {}[];
}

export enum MoviesActionTypes {
  SEARCH = 'SEARCH',
}

export interface SearchAction {
  type: MoviesActionTypes.SEARCH;
  payload: {};
}

Если я правильно понимаю, то мне нужно правильно указать тип в payload SearchAction...но как его указать? Туда будет приходить сложный объект. По ключу films я буду вытаскивать массив объектов и записывать их в стейт.


Ответы (1 шт):

Автор решения: xydope

Ответ на ваш вопрос подразумевает типизацию не state, а actions

Конкретно в вашем примере, вам нужно указать тип payload для searchAction

export interface SearchAction {
  type: MoviesActionTypes.SEARCH;
  payload: {
        files: укажите тип files
     };
}

более подробный пример на несколько разных action пример в codeSandBox

очень полезный видеоматериал по типизации, в том числе по редюсерам.

Полезная статья по выведению action type

type MoviesState = {
  movies: string[]; //стринг, чтобы обозначить, что у нас просто массив названий фильмов, в целом, это пока не важно.
};

const initialState: MoviesState = {
  movies: []
};

enum actionsName {
  byActor,
  byMovie,
  byYear
}

type SearchByActor = {
  type: actionsName.byActor;
  payload: { actorName: string };
};

type SearchByYear = {
  type: actionsName.byYear;
  payload: { year: number };
};

type SearchByMovie = {
  type: actionsName.byMovie;
  payload: { movieName: string };
};

type SearchActions = SearchByActor | SearchByYear | SearchByMovie;

function moviesReducer(state = initialState, action: SearchActions) {
  //редюсер ничего не делает, просто возвращает стейт
  switch (action.type) {
    case actionsName.byActor:
      action.payload.actorName;
      return state;
    case actionsName.byYear:
      action.payload.year;
      return state;
    case actionsName.byMovie:
      action.payload.movieName;
      return state;
    default:
      return state;
  }
}
→ Ссылка