Introducing the Satisfies Operator in TypeScript 4.9
The typescript 4.9 announced a new operator - satisfies
(you can check it on official blog post)
Motivation
The goal of this operator is to ensure that some expression matches some type, but also want to keep the most specific type of that expression for inference purposes.
Let's say we want to have common color type and it can be a string or an RGB tuple:
type Color = string | { r: number; g: number; b: number };
const redColor = 'red' as Color;
// Errors:
// Property 'toUpperCase' does not exist on type 'Color'.
// Property 'toUpperCase' does not exist on type '{ r: number; g: number; b: number; }'
console.log(redColor.toUpperCase());
as Color
can't automatically understand whether normalizedRedColor
is a string or an object. We can't do operations with a string (toUpperCase()) or with an object (get property from object color.r).
We can do it just if we write as follows:
console.log(typeof redColor === 'string' && redColor.toUpperCase());
But it's hard to check the const type every time.
Example
The new satisfies
operator lets us validate that the type of an expression matches some type and validate that all the properties of color are compatible with a string or an object:
type Color = string | { r: number; g: number; b: number }; // type can be whether a string or an object
const stringColor = 'red' satisfies Color;
console.log(stringColor.toUpperCase()); // valid operation as stringColor is a string
const rgbColor = { r: 0, g: 0, b: 0 } satisfies Color;
console.log(rgbColor.r, rgbColor.b, rgbColor.g); // valid operation as stringColor is an object
const palette = {
red: { r: 255, g: 0, b: 0 },
black: 'black',
white: { r: 255, g: 255, b: 255 },
// Error
// Object literal may only specify known properties, and 'c' does not exist in type '{ r: number; g: number; b: number; }'
aqua: {r: 0, g: 255, c: 255}
} satisfies Record<string, Color>;
console.log(palette.red, palette.black, palette.white); // valid operation as palette is a string record of Color
As you can see satisfies
determined the correct type automatically and we don't need to do extra stuff. Also it can catch typo errors if it's not matched with the type.