Home > Net >  Typescript cannot pick the correct type for the payload
Typescript cannot pick the correct type for the payload

Time:01-18

I have this issue where I get the typing error that: Property 'id' does not exist on type 'Subject | Subject[]'. Property 'id' does not exist on type 'Subject[]'.

This is the whole file

`const initialState = [] as Subject[];

type Action = {
    type: string;
    payload: Subject | Subject[];
}

const reducer = (state: Subject[] = initialState, action: Action) => {
    switch (action.type) {
        case "SET_SUBJECTS":
            return action.payload;
        case "ADD_SUBJECT":
            return [...state, action.payload];
        case "REMOVE_SUBJECT":
            return state.filter((subject) => subject.id !== action.payload.id);
        default:
            return state;
    }
};`

If i remove the "Subject[]" as a possible type of the payload, the error dissapears, but I really connot understand why it wouldn't pick the Subject as the type and allow me to use the "id" property that it has.

I tried removing the Subject[], which works, but I cannot go forward without allowing an array as an input.

CodePudding user response:

You can use a type guard function to tell typescript that payload is Array of Subjects or this is just a Subject, like that:

function isSubject(payload : Subject | Subject[]): payload is Subject {
  return 'any property from Subject' in payload
}
function isSubjectArray(payload : Subject | Subject[]): payload is Subject[] {
  return Array.isArray(payload)
}

And add it under case "REMOVE_SUBJECT":

case "REMOVE_SUBJECT":
  if (isSubject(payload))
  return state.filter((subject) => subject.id !== action.payload.id);

I hope that I helped you :) If you want to learn more about advanced types, check this: https://www.typescriptlang.org/docs/handbook/advanced-types.html

CodePudding user response:

Because there is a possibility that the payload attribute is an array, so the id attribute would be inside one of the array positions and should be accessed as ...[x].id.

The same will happen if you put Subject | string, expecting it to be a string, you will get the same error.

  • Related