Skip to content

TypeScript 4.9: satisfies operator

2 min read • Posted on September 25, 2022 (Edited on Nov 21, 2022)

In their v4.9, the TypeScript team is releasing a new operator: satisfies (see blog post https://devblogs.microsoft.com/typescript/announcing-typescript-4-9-beta/#the-satisfies-operator).

Purpose

The purpose of satisfies is to enforce a constraint on a variable, without changing its type.

For instance, you want to say that a color is “either a string, or a RGB tuple”, which would give something like that:

type RGB = readonly [red: number, green: number, blue: number];
type Color = { value: RGB | string };
const myColor: Color = { value 'red' };

But now, we don’t know whether myColor.value is a string or a tuple. So we cannot do something like myColor.value.toUpperCase() (even if it’s actually a string).

In TS 4.9, it’ll be possible to do this (TypeScript Playground):

type RGB = readonly [red: number, green: number, blue: number];
type Color = { value: RGB | string };
const myColor = { value: "red" } satisfies Color; // works
const myIncorrectColor = { value: 100 } satisfies Color; // throws error
myColor.value.toUpperCase(); // valid operation as myColor is a string

Combining as const and satisfies

As expected, you combine as const and satisfies (TypeScript Playground).

type RGB = readonly [red: number, green: number, blue: number];
type Color = RGB | string;
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [1, 2, 3],
} satisfies Record<string, Color>;
console.log(palette.green);
// ^? green is string
const constantPalette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [1, 2, 3],
} as const satisfies Record<string, Color>;
console.log(constantPalette.green);
// ^? green is "#00ff00"

Note: the order matters. While as const satisfies <type> works, the opposite isn’t true: satisfies <type> as const will throw a TS error (TypeScript Playground):

type RGB = readonly [red: number, green: number, blue: number];
type Color = RGB | string;
const invalidPalette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [1, 2, 3],
} satisfies Record<string, string | RGB> as const; // throws an error