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.