Búsqueda de sitios web

reactjs - Typescript y función Reducer con múltiples opciones de payload


Soy muy nuevo en TypeScript y estoy intentando escribir una función reducer con tres posibles valores de payload: ningún valor, una cadena o un número. Estoy usando un tipo de unión discriminada y por lo que he leído creo que mi código debería funcionar, pero no lo está haciendo.

type StateType = {
  isModalOpen: boolean;
  modalContent: string;
  people: {
    id: number;
    name: string;
  }[];
};

type NoPayloadAction = {
  type: string;
};

type NamePayloadAction = {
  type: string;
  payload: {
    name: string;
  };
};

type IdPayloadActionType = {
  type: string;
  payload: {
    id: number;
  };
};

type ActionType = NoPayloadAction | NamePayloadAction | IdPayloadActionType;

const ACTIONS = {
  ADD_ITEM: 'ADD_ITEM',
  NO_ACTION: 'NO_ACTION',
  CLOSE_MODAL: 'CLOSE_MODAL',
  REMOVE_ITEM: 'REMOVE_ITEM',
};

// reducer function
const reducer = (state: StateType, action: ActionType) => {
  switch (action.type) {
    case ACTIONS.ADD_ITEM:
      return {
        people: [
          ...state.people,
          { id: new Date().getTime(), name: action.payload.name },
        ],
        isModalOpen: true,
        modalContent: 'item added',
      };
    case ACTIONS.NO_ACTION:
      return { ...state, isModalOpen: true, modalContent: 'enter a value' };
    case ACTIONS.CLOSE_MODAL:
      return { ...state, isModalOpen: false, modalContent: '' };
    case ACTIONS.REMOVE_ITEM:
      const newPeople = state.people.filter(
        (person) => person.id !== action.payload.id
      );
      return {
        people: [...newPeople],
        isModalOpen: true,
        modalContent: 'item removed',
      };
    default:
      return state;
  }
};

Typescript está generando dos errores: Las líneas a continuación generan este error: La propiedad 'payload' no existe en el tipo 'ActionType'. La propiedad 'payload' no existe en el tipo 'NoPayloadAction'

{ id: new Date().getTime(), name: action.payload.name },

(person) => person.id !== action.payload.id

El tipo NoPayloadAction no tiene una carga útil, pero los otros dos sí, y por lo que entiendo, coinciden con sus tipos ya que uno tiene un campo id:number y el otro tiene un campo name:string. Estoy realmente desconcertado por esto.

Respuesta #1

En este momento, no hay garantía de que lo que se esté pasando a su variable action no sea un NoPayloadAction. Si está seguro de que su variable action tiene una carga útil, siempre puede usar la palabra clave as para decirle a TypeScript que usted sabe qué es la variable. Por ejemplo:

return { id: new Date().getTime(), name: (action as NamePayloadAction).payload.name },