Luke Oliff.

TIL: TypeScript satisfies Checks Your Object and Keeps Its Keys

·TIL·2 min read·Luke Oliff
TL;DR

The TypeScript satisfies operator, added in TypeScript 4.9, checks a value against a type without replacing the type TypeScript worked out for it. Write satisfies Record<string, Route> after the object instead of : Record<string, Route> before it, and a typo like routes.hoem fails to compile.

satisfies checks an object against a type and keeps everything TypeScript already knows about it. The TypeScript satisfies operator came in with TypeScript 4.9. The old way puts a type annotation (the : Type after the name) on the variable. Record<string, Route> means an object with any string as a key and a Route as each value:

type Route = { path: string; auth?: boolean };

const routes: Record<string, Route> = {
  home: { path: "/" },
  admin: { path: "/admin", auth: true },
};

routes.hoem; // no error

The annotation says any string is a valid key, so the typo gets through. Move the type to the end with satisfies:

const routes = {
  home: { path: "/" },
  admin: { path: "/admin", auth: true },
} satisfies Record<string, Route>;

routes.hoem; // error: Property 'hoem' does not exist

With TypeScript satisfies, every route still has to have a path. TypeScript just keeps the two real key names, home and admin, as well.

When to use TypeScript satisfies instead of as

as tells the compiler (the tool that checks your types) to trust you, so { home: {} } as Record<string, Route> gets through with no path at all. Use TypeScript satisfies when you want the check, and as only when you know something the compiler can’t.