'How to create a generic interface or type that accepts tow different interfaces that go under single array?
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!)
Solution 1:[1]
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)
}
Solution 2:[2]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | coglialoro |
Solution 2 |