`as` — "Trust Me, TypeScript"
Type Assertions
`as Type` tells TS to treat a value as a specific type. Use sparingly — assertions can hide real bugs.
What you'll learn
- Use `as Type` correctly
- Use `as const` to lock down literal types
- Recognize the `!` non-null assertion
A type assertion tells TypeScript “I know this is type X — trust me.” TS doesn’t verify; it just changes its view of the type.
as Type
const value = JSON.parse("{}"); // any
const user = value as User; // treated as User The as is a type-only construct — it has zero runtime effect.
When to Use Assertions
Sparingly. Legitimate cases:
- DOM queries that return broad types:
const input = document.getElementById("email") as HTMLInputElement; - After validating with your own code:
if (isValidUser(data)) {
const user = data as User; // ✗ usually unnecessary — predicates already narrow
} - Working around library types that are too broad
When NOT to Use Assertions
Don’t use as to silence errors you don’t understand. The TS
error is usually trying to tell you about a real bug.
The Non-Null Assertion — !
const el = document.getElementById("nav")!; // asserts not null ! after an expression asserts “this isn’t null or undefined”.
Same caveats — convenient, but if you’re wrong, it crashes.
as const
A special assertion that locks in the literal type of an expression:
const themes = ["light", "dark"] as const;
// type: readonly ["light", "dark"]
const config = { mode: "dev" } as const;
// type: { readonly mode: "dev" } Without as const:
const themes = ["light", "dark"];
// type: string[] as const is great for:
- Configuration objects with known literal values
- Enum-like arrays / objects
- Letting the type inference produce narrow types
Double Assertions (Avoid)
const x = "hi" as unknown as number; TS lets you double-assert through unknown to bypass safety
checks. Almost always a code smell. If you genuinely need this,
your types are wrong upstream.
satisfies — A Safer Alternative
Sometimes you want to check that a value conforms to a type WITHOUT widening:
type Config = Record<string, "dev" | "prod">;
const config = {
api: "dev",
cdn: "prod",
} satisfies Config;
config.api; // "dev" — narrow type preserved satisfies lets you validate without losing inferred narrow types.
Prefer it over as when you’re checking conformance.
Up Next
Discriminated unions — the single most useful pattern in TS.
Discriminated Unions →