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:
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!
CodePudding user response:
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,
}))
}
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
.