

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Object Literal Types
incomplete
2: Extra Properties
incomplete
3: Optional Object Properties
incomplete
4: Empty Object Type
incomplete
5: Discriminated Unions
incomplete
6: Sets
incomplete
7: Maps
incomplete
8: Dynamic Keys
incomplete
9: Dynamic Default Properties
incomplete
10: PropertyKey
incomplete
11: Readonly Modifier
incomplete
12: 'As Const' and Object.freeze
incomplete
13: Satisfies
incomplete
14: Function Overloads
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
The satisfies operator validates that a value matches a specific type without changing its inferred type. It solves a common pain point in TypeScript's type system. Before satisfies, you often had to choose between:
Here's an example:
// Using type inference (flexible but might miss errors)
const colors = {
red: "#ff0000",
green: "#00ff00",
blue: 255, // same as hex "#0000ff"
// "classic Lane-style typo" - Allan
yelow: "#ffff00",
};
To get around this, we can create an explicit type, and use that to catch typos:
type ColorMap = {
red: string | number;
green: string | number;
blue: string | number;
yellow: string | number;
};
const colorsTyped: ColorMap = {
red: "#ff0000",
green: "#00ff00",
blue: 255,
// Error: "yelow" is not in type ColorMap
yelow: "#ffff00",
};
The trouble is that because our ColorMap type uses string | number for the values, we lose the more specific type information:
// redHex is now 'string | number'
// where it used to be 'string'
type redHex = typeof colorsTyped.red;
This means that despite the value colorsTyped.red being a string, its string | number type will cause errors if you try to call string methods on it:
// Error: Property 'toUpperCase' does not exist on type 'string | number'
const redUpper = colorsTyped.red.toUpperCase();
The satisfies operator gives us the best of both worlds:
type ColorMap = {
red: string | number;
green: string | number;
blue: string | number;
yellow: string | number;
};
const colorsSatisfies = {
red: "#ff0000",
green: "#00ff00",
blue: 255,
yellow: "#ffff00",
// Error: "yelow" is not in type ColorMap
// yelow: "#ffff00"
} satisfies ColorMap;
// We keep the narrowed types!
type RedHexSatisfies = typeof colorsSatisfies.red;
const redUpper = colorsSatisfies.red.toUpperCase(); // "#FF0000"
The lead architect at Support.ai (you!) created the MailPreferences type so that no one would accidentally create malformed mail preferences objects.
...someone did it anyway, but at least TypeScript caught it!