I have a function getProperty
it will accept different kinds of args in my test case i have two different args firstname
and lastName
In my getProperty
function i have if statement that check which args are coming in and then returns that one.
From my understanding Generic is what i need to use but I'm getting error Property 'firstName' does not exist on type 'T'.
How do i correctly type Generic for this to work?
type TdataV1 = {
firstName: string
}
type TdataV2 = {
lastName: string
}
const dataV1: TdataV1 = {
firstName: 'Name',
}
const dataV2: TdataV2 = {
lastName: 'Name',
}
const getProperty = <T>(data: T): string => {
if (data.firstName) {
return data.firstName
}
if (data.lastName) {
return data.lastName
}
}
getProperty<TdataV1>(dataV1)
getProperty<TdataV2>(dataV2)
CodePudding user response:
Your types have an empty intersection (no common fields) so you should just write this:
const getProperty = (data: TdataV1 | TdataV2): string => {
if ('firstName' in data) {
return data.firstName
}
if ('lastName' in data) {
return data.lastName
}
}
TypeScript's type guards will get you the correct type inside every if
code block.
You can check this playground demo too see it in action.
CodePudding user response:
I would do it like following: with another arg in your function to add more type protection cf. https://www.typescriptlang.org/docs/handbook/2/keyof-types.html
type TdataV1 = {
firstName: string;
};
type TdataV2 = {
lastName: string;
};
const dataV1: TdataV1 = {
firstName: 'Name',
};
const dataV2: TdataV2 = {
lastName: 'Name',
};
const getKeyProperty = <T>(data: T, key: keyof T) => {
if (data[key]) return data[key];
};
getKeyProperty<TdataV1>(dataV1, 'firstName');
getKeyProperty<TdataV2>(dataV2, 'lastName');
CodePudding user response:
Since you said you don't want to list out all the possible types, it seems like generics aren't necessary for this. You can just do something like this:
const getProperty = (data: { [key: string]: string }): string => {
if (data.firstName) {
return data.firstName
}
if (data.lastName) {
return data.lastName
}
}