DEV Community

Nhan Nguyen
Nhan Nguyen

Posted on

Beginner's TypeScript #12

Image description

Narrowing Down Union Types

Consider this function:

const coerceAmount = (amount: number | { amount: number }) => {};
Enter fullscreen mode Exit fullscreen mode

What this is saying is that what we pass into coerceAmount can be either a number or an object that contains an amount.

Inside of the coerceAmount function, we can check if amount.amount exists, then return it. Otherwise, return amount:

const coerceAmount = (amount: number | { amount: number }) => {
  if (amount.amount) {
    return amount.amount;
  }
  return amount;
};
Enter fullscreen mode Exit fullscreen mode

TypeScript gives us an error.

Hovering over amount.amount tells us:

Property 'amount' does not exist on type number.
Enter fullscreen mode Exit fullscreen mode

This is a TypeScript quirk where you can not access a property unless you know it is there.

One way to fix the type error is updating our if to check if the typeof amount is an object. If so, return amount.amount otherwise just return amount.

const coerceAmount = (amount: number | { amount: number }) => {
  if (typeof amount === 'object') {
    return amount.amount;
  }
  return amount;
};
Enter fullscreen mode Exit fullscreen mode

This would also work by checking if the typeof amount is a number and then returning the amount. Otherwise, return amount.amount:

const coerceAmount = (amount: number | { amount: number }) => {
  if (typeof amount === 'number') {
    return amount;
  }
  return amount.amount;
};
Enter fullscreen mode Exit fullscreen mode

Using the typeof operator to narrow down different branches of a union type is a really powerful technique.

It is also really useful when interfacing with APIs that you did not create.


I hope you found it useful. Thanks for reading. 🙏

Let's get connected! You can find me on:

Top comments (0)