{"slug": "you-are-lying-to-your-compiler-use-satisfies-instead-of-as", "title": "You Are Lying to Your Compiler. Use \"satisfies\" Instead of \"as\".", "summary": "A developer argues that TypeScript's `as` type assertion silently suppresses compiler errors and can ship runtime bugs, and recommends the `satisfies` operator introduced in TypeScript 4.9 instead. The writeup shows that `satisfies` validates object literals against a type while preserving literal types, so typos and missing properties are caught at compile time and keys like `colors.pink` produce errors, while `as` remains appropriate for cases such as DOM queries where the compiler cannot know the runtime value.", "body_md": "You are lying to the compiler. It is time to stop.\n\nI am going to say something that might make some of you uncomfortable. Every time you write `as` in TypeScript, you are basically telling the compiler to shut up and trust you. That feels powerful in the moment. It is also how you ship bugs to production.\n\nThe `as` keyword does not check anything. It is a command, not a question. You are saying \"I know better than you, compiler, and I don't need your help.\" Sometimes that is true. Most of the time it is not.\n\nTypeScript 4.9 gave us something better. It is called satisfies. Once you understand what it does, you will wonder how you ever lived without it.\n\n**What `as` actually does**\n\nLet me be clear about the mechanics here. When you write:\n\n`const user = { name: \"Alice\" } as User;`\n\nYou are doing a type assertion. You are overriding TypeScript's type inference with your own judgment. The compiler will check that the assertion is plausible. It will not verify that your object actually has all the required properties.\n\nHere is the problem. `as` suppresses errors. It does not catch mistakes. It hides them.\n\nLook at this:\n\n``` js\ninterface User {\n  name: string;\n  email: string;\n}\n\nconst user = {\n  name: \"Alice\",\n  username: \"alice123\"\n} as User;\n```\n\nTypeScript will not complain. But you just created an object that claims to be a `User` while missing the email property and carrying an extra `username` field. If your code later tries to read `user.email`, you get undefined at runtime.\n\nThis is exactly the kind of silent failure TypeScript was supposed to prevent.\n\n**Enter satisfies**\n\nThe satisfies operator does something different. Instead of overriding the type, it validates it.\n\nSame example with satisfies:\n\n``` js\nconst user = {\n  name: \"Alice\",\n  email: \"alice@example.com\"\n} satisfies User;\n```\n\nIf you misspell `email` as `emial`, or forget it entirely, TypeScript throws an error immediately. Your IDE will yell at you. The compiler will refuse to build.\n\nBut here is the beautiful part. `satisfies` does not widen your types.\n\nWith a type annotation like `const user: User = {...}`, TypeScript treats `user.name as string`. With `satisfies`, TypeScript keeps the literal type. If you wrote `name: \"Alice\"`, then `user.name` is exactly `\"Alice\"`, not just string.\n\n**The difference in practice**\n\nLet me show you a real scenario that changed how I write TypeScript.\n\nImagine you are defining a color palette:\n\n```\ntype ColorConfig = Record<string, [number, number, number]>;\n\n// With annotation, you lose precision\nconst colors: ColorConfig = {\n  red: [255, 0, 0],\n  green: [0, 255, 0],\n  blue: [0, 0, 255],\n};\n\ncolors.red;   // Type: [number, number, number]\ncolors.pink;  // No error. TypeScript doesn't know \"pink\" doesn't exist\n```\n\nNow with `satisfies`:\n\n``` js\nconst colors = {\n  red: [255, 0, 0],\n  green: [0, 255, 0],\n  blue: [0, 0, 255],\n} satisfies ColorConfig;\n\ncolors.red;   // Type: [255, 0, 0]. Precise.\ncolors.pink;  // Error: Property 'pink' does not exist\n```\n\nThat second example gives you autocomplete for the actual keys, catches typos, and preserves the exact literal values. This is what TypeScript was always supposed to feel like.\n\n**When you should still use as**\n\nI am not saying `as` is always wrong. There are legit cases where you know more than the compiler.\n\nThe classic one is DOM queries:\n\n`const element = document.querySelector(\"#app\") as HTMLDivElement;`\n\nTypeScript cannot possibly know what element is on the page. It returns `Element | null`. You know it is a `div`. This is where `as` earns its keep.\n\nOther legit uses include type guards and certain edge cases where you are avoiding any. But for object literals, config files, and type validation, which is where most of us spend our time, `satisfies` is the better tool.\n\n**The mental model**\n\nHere is how I think about it.\n\nType annotation (`: Type`) means \"this variable is this type. I don't care about the specific value.\"\n\n`as` means \"I know better than you, compiler. Don't check.\"\n\n`satisfies` means \"make sure this value fits this shape, but keep the precise type I inferred.\"\n\nThe third option is almost always what you actually want.\n\n**Stop lying. Start validating.**\n\nThe TypeScript community is already moving this direction. There are even lint rule proposals to prefer `satisfies` over `as` for exactly the reasons I described.\n\nNext time you reach for `as`, ask yourself one question. Am I actually smarter than the compiler here, or am I just being lazy?\n\nIf it is the second one, try `satisfies`. Your future self will thank you.", "url": "https://wpnews.pro/news/you-are-lying-to-your-compiler-use-satisfies-instead-of-as", "canonical_source": "https://dev.to/ogeobubu/you-are-lying-to-your-compiler-use-satisfies-instead-of-as-55j2", "published_at": "2026-09-27 21:07:32+00:00", "updated_at": "2026-09-27 22:01:07.799088+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["TypeScript"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/you-are-lying-to-your-compiler-use-satisfies-instead-of-as", "markdown": "https://wpnews.pro/news/you-are-lying-to-your-compiler-use-satisfies-instead-of-as.md", "text": "https://wpnews.pro/news/you-are-lying-to-your-compiler-use-satisfies-instead-of-as.txt", "jsonld": "https://wpnews.pro/news/you-are-lying-to-your-compiler-use-satisfies-instead-of-as.jsonld"}}