---
title: "TIL: TypeScript satisfies Keeps Your Object's Keys"
description: The TypeScript satisfies operator checks an object against a type but keeps its real key names, so a typo in a key becomes a compile error.
canonical: https://lukeocodes.dev/til-typescript-satisfies
type: article
locale: en_GB
published: 2026-11-03T00:00:00.000Z
modified: 2026-11-03T00:00:00.000Z
authors:
  - Luke Oliff
section: TIL
tags:
  - TIL
  - TypeScript
  - satisfies
  - type checking
  - typescript 4.9
feed: https://lukeocodes.dev/rss.xml
search: https://lukeocodes.dev/search.json?q={query}
schema:
  - "@context": https://schema.org
    "@graph":
      - "@type": WebSite
        "@id": https://lukeocodes.dev/#website
        url: https://lukeocodes.dev
        name: Luke Oliff
        alternateName: lukeocodes
        inLanguage: en
        publisher:
          "@id": https://lukeocodes.dev/authors/luke#person
        description: Personal blog and writing by Luke Oliff — developer relations, voice AI, developer experience.
        potentialAction:
          - "@type": SearchAction
            target:
              "@type": EntryPoint
              urlTemplate: https://lukeocodes.dev/blog/search?q={search_term_string}
            query-input: required name=search_term_string
      - "@type": Person
        "@id": https://lukeocodes.dev/authors/luke#person
        name: Luke Oliff
        url: https://lukeocodes.dev/authors/luke
        description: Engineer and developer relations leader. Writing about developer relations, AI, and the voice industry, from the UK.
        mainEntityOfPage: https://lukeocodes.dev/authors/luke
        givenName: Luke
        familyName: Oliff
        image: https://lukeocodes.dev/authors/luke.jpg
        jobTitle: Engineer and developer relations leader
        sameAs:
          - https://www.linkedin.com/in/lukeocodes
          - https://github.com/lukeocodes
          - https://bsky.app/profile/lukeocodes.dev
          - https://x.com/lukeocodes
          - https://hashnode.com/@lukeocodes
          - https://dev.to/lukeocodes
        knowsAbout:
          - Developer Relations
          - Developer Experience
          - Voice AI
          - Text-to-Speech
          - Answer Engine Optimisation
          - Search Engine Optimisation
          - Open Source
          - Developer Tooling
          - API Design
          - Speech-to-Text
          - Voice Agents
          - Community Building
        knowsLanguage:
          - English
        nationality: British
        alumniOf:
          - "@type": Organization
            name: The Open University
  - "@context": https://schema.org
    "@graph":
      - "@type": Person
        "@id": https://lukeocodes.dev/authors/luke#person
        name: Luke Oliff
        url: https://lukeocodes.dev/authors/luke
        description: Engineer and developer relations leader. Writing about developer relations, AI, and the voice industry, from the UK.
        mainEntityOfPage: https://lukeocodes.dev/authors/luke
        givenName: Luke
        familyName: Oliff
        image: https://lukeocodes.dev/authors/luke.jpg
        jobTitle: Engineer and developer relations leader
        sameAs:
          - https://www.linkedin.com/in/lukeocodes
          - https://github.com/lukeocodes
          - https://bsky.app/profile/lukeocodes.dev
          - https://x.com/lukeocodes
          - https://hashnode.com/@lukeocodes
          - https://dev.to/lukeocodes
        knowsAbout:
          - Developer Relations
          - Developer Experience
          - Voice AI
          - Text-to-Speech
          - Answer Engine Optimisation
          - Search Engine Optimisation
          - Open Source
          - Developer Tooling
          - API Design
          - Speech-to-Text
          - Voice Agents
          - Community Building
        knowsLanguage:
          - English
        nationality: British
        alumniOf:
          - "@type": Organization
            name: The Open University
      - "@type": BlogPosting
        "@id": https://lukeocodes.dev/til-typescript-satisfies#article
        headline: "TIL: TypeScript satisfies Keeps Your Object's Keys"
        alternativeHeadline: "TIL: TypeScript satisfies Checks Your Object and Keeps Its Keys"
        description: The TypeScript satisfies operator checks an object against a type but keeps its real key names, so a typo in a key becomes a compile error.
        datePublished: 2026-11-03T00:00:00.000Z
        dateModified: 2026-11-03T00:00:00.000Z
        url: https://lukeocodes.dev/til-typescript-satisfies
        mainEntityOfPage: https://lukeocodes.dev/til-typescript-satisfies
        inLanguage: en
        author:
          - "@id": https://lukeocodes.dev/authors/luke#person
        isPartOf:
          "@id": https://lukeocodes.dev/#website
        keywords: TIL, TypeScript, satisfies, type checking, typescript 4.9
        articleSection: TIL
        abstract: "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."
        speakable:
          "@type": SpeakableSpecification
          cssSelector:
            - .post-tldr
            - h1
        image: https://lukeocodes.dev/og.png?h=TIL%3A+TypeScript+satisfies+Keeps+Your+Object%27s+Keys&d=The+TypeScript+satisfies+operator+checks+an+object+against+a+type+but+keeps+its+real+key+names%2C+so+a+typo+in+a+key+becomes+a+compile+error.&e=Writing
        wordCount: 222
        timeRequired: PT2M
        publisher:
          "@id": https://lukeocodes.dev/authors/luke#person
      - "@type": BreadcrumbList
        itemListElement:
          - "@type": ListItem
            position: 1
            name: Home
            item: https://lukeocodes.dev
          - "@type": ListItem
            position: 2
            name: Writing
            item: https://lukeocodes.dev/blog
          - "@type": ListItem
            position: 3
            name: "TIL: TypeScript satisfies Keeps Your Object's Keys"
            item: https://lukeocodes.dev/til-typescript-satisfies
---

[Luke Oliff.](/)

- [Blog](/blog)
- [CV](/cv)
- [Uses](/uses)
- [User manual](/user-manual)
- [Living with ADHD](/living-and-working-with-adhd)
- [RSS](/rss.xml)

[Luke Oliff · Writing](/blog)

# TIL: TypeScript satisfies Checks Your Object and Keeps Its Keys

Nov 2026 · [TIL](/blog/category/til) · 2 min read · [Luke Oliff](/authors/luke)

**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](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html). 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:

```ts
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`:

```ts
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.

[All posts](/blog) →

## Search this site

`GET https://lukeocodes.dev/search.json?q=<words>` returns matching posts as JSON, each with its page URL and its markdown URL. Add `&limit=<1-50>` for more than 10. How it works: [/blog/search](https://lukeocodes.dev/blog/search.md).

```sh
curl "https://lukeocodes.dev/search.json?q=developer+relations"
```

---

© 2026 Luke Oliff. Posts live at the root of this site.

- [GitHub](https://github.com/lukeocodes)
- [LinkedIn](https://www.linkedin.com/in/lukeocodes)
- [X](https://x.com/lukeocodes)
- [Bluesky](https://bsky.app/profile/lukeocodes.dev)
- [Email](mailto:luke@lukeoliff.com)
- [RSS](/rss.xml)

## Cookies

This site sets one analytics cookie, from Google Analytics, and only in a browser that accepts the cookie banner. A client that does not run scripts sets no cookies, so there is nothing to accept or decline here.

[Cookie policy](/cookies)
