Home > OS >  Get correct types for reusable function with different 'data' args object
Get correct types for reusable function with different 'data' args object

Time:10-16

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
  }
}
  • Related