Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

131
Vistas
Typescript reducer's switch case typeguard doesn't work with object spread

I have a reducer that does different actions depending on the action.type, actions payload is different for certain actions.

    export enum ActionType {
      UpdateEntireState = "UPDATE_ENTIRE_STATE",
      UpdateStateItem = "UPDATE_STATE_ITEM"
    }
    
    type TypeEditData = {
      id: string;
      name: string;
      surname: string;
      age: number;
    };
    
    export type State = TypeEditData[];
    export type Action = UpdateEntireState | UpdateStateItem;
    
    type UpdateEntireState = {
      type: ActionType.UpdateEntireState;
      payload: State;
    };
    
    type UpdateStateItem = {
      type: ActionType.UpdateStateItem;
      payload: { id: string; data: TypeEditData };
    };
    
    export function reducer(state: State, action: Action): State {
      const { type, payload } = action;
    
      switch (type) {
        case ActionType.UpdateEntireState: {
          return [...payload];
        }
        case ActionType.UpdateStateItem: {
          const person = state.filter((item) => item.id === payload.id);
          return [...state, person[0]];
        }
        default: {
          throw Error("Wrong type of action!");
        }
      }
    }

This code won't work, the errors will say that my action payload can be State or { id: string; data: TypeEditData }. However, if I access the payload property inside switch case using dot notation like so

return [...action.payload];

There won't be any errors and the type guard will work fine. How const { type, payload } = action; differs from action.type and action.payload in terms of types and why doesn't typeguard work with spread syntax?

TS version - 4.3.4

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

The issue is that you've defined payload before there was type information available on action, so it has the union type

State | {
    id: string;
    data: TypeEditData;
};

Define a local variable or simply use action.payload within each case statement and the compiler knows what type it has:

export function reducer(state: State, action: Action): State {
  // const { type, payload } = action;

  switch (action.type) {
    case ActionType.UpdateEntireState: {
      return [...action.payload];
    }
    case ActionType.UpdateStateItem: {
      const person = state.filter((item) => item.id === action.payload.id);
      return [...state, person[0]];
    }
    default: {
      throw Error("Wrong type of action!");
    }
  }
}

Variable type is established explicitly at declaration (e.g. const a: string) or implicitly at initialization (e.g. a = 4). Subsequent typeguard constructs are not used to re-evaluate the type of the variable. On the contrary, since the type of the variable is already defined at that point, that type is used to validate whether the later construct is valid for the variable.

about 4 years ago · Juan Pablo Isaza Denunciar

0

Action interface by default comes with type property.

export interface Action {
    type: string;
}

If you can extend Action interface to add payload as array of objects then typescript wont throw you an error. Something like this, in your reducer function you can use like this

interface CustomAction extends Action{
    payload: Array<any>
}


export function reducer(state: State, action: CustomAction): State {
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda