Search code examples
reactjstypescriptreduxreact-reduxredux-toolkit

How to get the payload type in redux typescript


I am using react typescript with the redux store. I have two types of object types coming from the payload. I want to identify the payload object type so that I can do some action based on the type.

These are the types

type Car = {
  carID: number,
  color: string,
  model: string,
  score: number
}

type Bus = {
  busID: number,
  model: string,
  type: string
}

type Transports = {
    [id: number]: Array<Car | Bus>;
}

interface State  {
  data: Transports
}

and in the reducer, I have a delete method in which I am getting an error: Types of parameters 'x' and 'value' are incompatible. Type 'Car | Bus' is not assignable to type 'Car'. on forEach loop

deleteVehicle: (state: State, action: PayloadAction<Car | Bus>) => {
      if("carID" in action.payload){
        const { id, carID } = action.payload;
        let vehicles = { ...state.data };
        vehicles[id].forEach((x: Car) => {
         if (x.carID === carID) x.score = 0;
       });
      state.data = { ...vehicles };
    }
}

Solution

  • You could check if a key exists so Typescript will infer the correct type. This is called a type guard.

    deleteVehicle: (state: State, action: PayloadAction<Car | Bus>) => {
      const { id, carID } = action.payload;
    
      const vehicles = state.data;
      
      return {
        ...vehicles,
        vehicles[id]: vehicles[id].map((vehicule) => {
          if ('carId' in vehicule && vehicule.carId === carId) {
            // vehicule will be of type Car
            vehicule.score = 0;
          }
    
          return vehicule;
        }
      }