as Type Assertions (incl. double assertions)
Last updated: 2026-10-22
as Type Assertions (incl. double assertions)
A type assertion (as) tells the compiler "I know this value's type better than you do — treat it as T." It never changes the runtime value or performs a conversion; it simply overrides inference. Use it when you hold information the compiler cannot get (DOM queries, third-party unknown values), knowing a wrong assertion goes unchecked.
| Group | Narrowing & Assertions |
|---|---|
| Kind | Operator |
| Strict mode | Not required |
ℹ️ Info The editor transpiles TypeScript to JavaScript and runs it (no type checking); see each example's Output for type-check results.
📝 Syntax
const el = document.getElementById("root") as HTMLElement;
const data = JSON.parse(raw) as Config; // common: collapse unknown/any to a concrete type
// When two types share nothing, a double assertion is required (a smell)
const n = value as unknown as Config;
⚙️ Parameters
| as T | Asserts the expression as T. TS only permits assertions between "overlapping" types (one assignable to the other); otherwise it errors |
|---|---|
| as unknown as T | Double assertion: via unknown first, bypassing the overlap check. Almost always a sign of a modeling problem |
Returns:Assertions emit no runtime code — transpiled output is identical without the as; only the compile-time type view changes.
▶ Example
Edit the code below and click Try it to see the transpiled result:
Output:
20 dark
string
(Runtime output after transpilation. Note the second line: after asserting {w:number} the runtime value is still the string "1920x1080" — assertions do not transform values, typeof legacy is "string". A wrong assertion only surfaces at runtime)
💡 Notes
⚠️ Note An assertion is not a conversion and does nothing at runtime. Assert a string as a number and call toFixed: it compiles, then throws at runtime — every assertion error is deferred to runtime.
ℹ️ Info TS 4.9 added the satisfies operator, which validates against a type while preserving literal inference — many cases that once required as can now use the safer satisfies.
💡 Tip Preference order: guard narrowing > unknown + narrowing > as > as unknown as. Reserve assertions for cases where you genuinely know more than the compiler, and suspect your design whenever a double assertion appears.
🏷️ Related Narrowing & Assertions
💡 Related cases
More cases coming soon.
📚 Related tutorials
❓ FAQ
Q Why can't two completely unrelated types be asserted directly?
A TS requires one direction of assignability (an overlap) between asserted types to block obviously wrong casts like string to number. When truly needed you go as unknown as T — the ceremony exists to make you pause and reconsider.
Q How does as differ from a type annotation (: T)?
A An annotation constrains and checks: the value must actually satisfy T or you get an error; as bypasses the check by declaration. Prefer annotations — they keep compiler protection, while as is you signing off personally.
Q Which is preferred in JSX files, <T>expr or as?
A In .tsx files the angle-bracket assertion <T>expr conflicts with JSX syntax and is unavailable — use expr as T consistently. The two forms are semantically identical.