Reputation: 2158
So I've came across this problem enough times that I figure it's time to ask:
How do you define functions that take two object types in Typescript?
I've also read https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html, and understand that the existing union |
doesn't really work well for objects as it will only contain elements both objects have.
A Contrived Example
type Person = {
name: string;
age: number;
};
type Pet = {
owner: string;
};
/*
* We'd like this function to be able to take two different objects as args
*/
const randomFunction = (myObject: Person | Pet) => {
// PROBLEM:
// Property 'age' does not exist on type 'Person | Pet'.
if (typeof myObject.age !== 'undefined') console.log(myObject.age);
};
Problem: Property 'age' does not exist on type 'Person | Pet'.
So how do you deal with this? I'd like to be able to pass in two different object types for a simple function.
Is what I'm trying to do not "TypeScripty" or not recommended?
To get rid of the TypeScript squigglies, it seems I'd need to split it out into a different function.
Thanks!
Upvotes: 1
Views: 2565
Reputation: 2158
So the solution is to use a TypeGuard as per @Idruskis.
The solution is largely written out here: https://medium.com/ovrsea/checking-the-type-of-an-object-in-typescript-the-type-guards-24d98d9119b0
type Person = {
name: string;
age: number;
};
type Pet = {
owner: string;
};
// Typeguard
function isPerson(
data: Pet | Person,
): data is Person {
if ((data as Person).age) {
return true;
}
return false;
}
const randomFunction = (myObject: Person | Pet) => {
if (!isPerson(myObject)) return;
// No error!
if (typeof myObject.age !== 'undefined') console.log(myObject.age);
};
Upvotes: 4