I want to be able to create a generic type that works with an array that accepts tow similar object but not totally equal, every thing works fine until I want to access a value that is not in both objects in this case the gender property.
// React state logic
interface Client {
name: string;
clientId: string;
weekId: string;
gender: string;
}
interface Program {
name: string;
clientId: string;
weekId: string;
type: string;
}
export interface StateInterface {
data: (Program | Client)[];
}
//In component Issue
const clientsArr = _globalContext.data.filter((el) => el.name === value);
// Error massage on gender Property
/*Property 'gender' does not exist on type 'Client | Program'.
Property 'gender' does not exist on type 'Program'.*/
console.log(clientsArr[0].gender!)
CodePudding user response:
This is correct behavior. At that point typescript has no way to know if that value is a Client
or a Program
. What can do is adding a property that allow you to narrow the type. Here's an example:
// Added `human` property just as an example, doesn't have to be a boolean
// You could do something like `type: "client"` and `type: "program"`,
// it would work aswell
interface Client {
human: true;
name: string;
clientId: string;
weekId: string;
gender: string;
}
interface Program {
human: false;
name: string;
clientId: string;
weekId: string;
type: string;
}
Then when you access it you check for your discriminating property:
if(clientsArr[0].human){
// At this point typescript can be sure that the property exists, so no error
console.log(clientsArr[0].gender)
}
CodePudding user response:
You can avoid this kind of type problem by type casting:
console.log((<Client>clientsArr[0])?.gender);
so It guarantees that clientsArr[0]
type should be Client
, otherwise console.log
shows undefined
.
Also maybe clientsArr[0]
is null
and the question mark before .gender
prevents from Cannot read properties of undefined
error.