njho
njho

Reputation: 2158

How do you define functions that take two object types in Typescript?

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

Answers (1)

njho
njho

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

Related Questions