Avoid `as Type` assertions — they tell TypeScript "trust me" and skip validation. If the runtime value doesn't match, your code crashes with no type error to warn you.
Why This Matters
Type assertions (`as Type`) bypass TypeScript's type checker entirely. When you write `data as User`, TypeScript stops verifying that `data` actually has the shape of `User`. If the runtime value is missing fields or has the wrong types, your code will access undefined properties and crash — with no compile-time warning. Every `as` assertion is a potential runtime error hiding from the type checker.
A type assertion tells TypeScript: "I know better than you — treat this value as this type." TypeScript obeys without checking. If you're wrong, the type system provides no safety net.
This is dangerous because assertions look like they provide type safety — the code has types, it compiles cleanly — but the types are lies. The runtime value might not match the asserted type, and TypeScript won't warn you.
Every as Type in your codebase is a place where TypeScript cannot help you catch bugs. The more assertions you have, the less value TypeScript provides.
The rule
Avoid as Type assertions. Instead, use type narrowing (typeof, instanceof, type guards, schema validation) to prove the type at runtime. Assertions are acceptable only in rare cases: test setup, type-safe wrappers around untyped libraries, and const assertions (as const).
Bad example
// BAD: asserting the API response is a Userasync function getUser(id: string): Promise<User> { const response = await fetch(`/api/users/${id}`); const data = await response.json(); return data as User; // What if the API returns an error object?}// BAD: asserting a DOM element typeconst input = document.getElementById("email") as HTMLInputElement;input.value = "test@example.com"; // crashes if the element doesn't exist or isn't an input
Good example
// GOOD: validate the response shapeimport { z } from "zod";const UserSchema = z.object({ id: z.string(), name: z.string(), email: z.string().email(),});async function getUser(id: string): Promise<User> { const response = await fetch(`/api/users/${id}`); const data = await response.json(); return UserSchema.parse(data); // throws with clear error if shape doesn't match}// GOOD: narrow the DOM element typeconst input = document.getElementById("email");if (input instanceof HTMLInputElement) { input.value = "test@example.com"; // type-safe}