Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

using a generic type to accept two different types of items as a parameter

this should be a simple use case, but I can’t seem to fine an example that covers it.

Basically I have a function that should be allowed to take two different objects, that are very similar. So, I would like to use the generic type. The function looks something like this:

const myFunction = <MyGenericType>(arrayOfObjects: MyGenericType[]) => {
  return arrayOfObjects.map((obj: MyGenericType) => ({
    id: obj.id,
    name: obj.name,
    someProperty: obj.someProperty || obj.someOtherProperty,
  }))
}

So for it’s usage these would be the two types that I could pass in as a parameter:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

type PotentialType1 = {
  id: string
  name: string
  someProperty: string
}


type PotentialType2 = {
  id: string
  name: string
  someOtherProperty: string
}

The issue is, if I try to do this, each of the properties accessed in myFunction get the following error:

Property X does not exist on type ‘MyGenericType’.

So, id, name and someProperty all don’t exist.

It seems to work flawlessly with the primitive types (such as string, number, etc), but how could I do this with the more complex ones?

Thanks!

>Solution :

The problem is that your function doesn’t know anything about MyGenericType. To let it know that this type will always have certain properties, you will need to add a constraint. In this case, it looks like you need your generic type to be one of two specific types, so you could tell your generic function that MyGenericType extends a union of those two types:

type PotentialType1 = {
  id: string
  name: string
  someProperty: string
}


type PotentialType2 = {
  id: string
  name: string
  someOtherProperty: string
}

const myFunction = <MyGenericType extends PotentialType1 | PotentialType2>(arrayOfObjects: MyGenericType[]) => {
  return arrayOfObjects.map((obj: MyGenericType) => ({
    id: obj.id,
    name: obj.name,
    someProperty: 'someProperty' in obj ? obj.someProperty : obj.someOtherProperty,
  }))
}

TypeScript Playground

In this example I’ve also had to change the setting of someProperty to use a ternary operator so TypeScript will narrow the type of obj instead of complaining that those properties don’t exist on something with the type PotentialType1 | PotentialType2.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading