Tom Dohnal

State-of-the-art frontend development

Back to postsWatch video
November 11, 2022 β€’ 4 min read

TypeScript satisfies operator

The problem

Imagine you're faced with the following problem:

You have a type City that can be either CityName or CityCoordinates:

type City = CityName | CityCoordinates;

CityName is a string representing one of the specified cities:

type CityName = "New York" | "Mumbai" | "Lagos";

CityCoordinates is an object with x and y properties denoting the coordinates of your city:

type CityCoordinates = {
  x: number;
  y: number;

And the User type has birthCity and currentCity, both of which are of type City:

type User = {
  birthCity: City;
  currentCity: City;

Then, you want to create a new variable user that adheres to the User type.

You want to assign "Mumbai" to the birthCity property (that's of the type CityName) and { x: 6, y: 3 } to the currentCity property (that's of the type CityCoordinates).

What you would normally do is something like this πŸ‘‡

const user: User = {
  birthCity: "Mumbai",
  currentCity: { x: 6, y: 3 },

That's all well and good and, as of TypeScript 4.8 of less, the only way to make sure that the user variable matches the shape of the User type.

Now, say you want to make the birthCity property of the user variable uppercase.

If you were to do that, however, you'd make TypeScript upset and get an error:

// yields this TypeScript error πŸ‘‡
// Property 'toUpperCase' does not exist on type 'City'.
//   Property 'toUpperCase' does not exist on type 'CityCoordinates'.

The way that TypeScript sees the birthCity property is that it can be either CityName or CityCoordinates.

It doesn't "know" that you want the user variable to have the CityName type for the birthCity and the CityCoordinates for the currentCity.

satisfies to the rescue

Before the satisfies keyword was introduced, there wasn't a good way to achieve this.

More specifically, it wasn't possible to both

  1. ensure that a variable matches the specified type
  2. make TypeScript infer a more specific type based on the values provided to this variable

Now that we've got the satisfies keyword, this very thing is now possible!

The syntax is as follows πŸ‘‡

const user = {
  birthCity: "Mumbai",
  currentCity: { x: 6, y: 3 },
} satisfies User

The inferred type of the user variable is going to be πŸ‘‡

  birthCity: "Mumbai";
  currentCity: {
    x: number;
    y: number;

This will enable us to access string-specific methods (like .toUpperCase()) on the birthCity property and access the x and y number properties on the currentCity variable πŸ‘‡

// we can call `toUpperCase`

// ...and we can access the `x` (or `y`) properties
// and call `number`-specific methods on them

And, on top of that, if we were to assign a value that doesn't match the User type to the user variable, we would get protected from type errors πŸ‘‡πŸ»

const user = {
  // assigning "Beijing" yields this error πŸ‘‡
  //   Type '"Beijing"' is not assignable to type 'City'
  birthCity: "Beijing",
  currentCity: { x: 6, y: 3 },
} satisfies User

const user = {
  name: 'Amy'
} satisfies User

In conclusion, with satisfies we can get the best of both worlds. Type safety saves us from runtime errors and powerful type inference gives us most specific types for free.

Source code

You can find the source code for this tutorial on Typescript Playground.

If you liked this tutorial, you can also check out and subscribe to my YouTube channel. Or/and subscribe to my newsletter to get notified when I publish new articles! πŸ‘‡

Subscribe to the newsletter

Stay up to date with state-of-the-art frontend development.

No spam. Unsubscribe any time.