Home > OS >  How to create a generic interface or type that accepts tow different interfaces that go under single
How to create a generic interface or type that accepts tow different interfaces that go under single

Time:03-20

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.

  • Related