Lesson 18 of 80
'as' tells the compiler to trust you, no checking; 'satisfies' checks against a type but keeps the more specific inferred type — two very different tools that look deceptively similar.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 2
`const el = document.getElementById("app") as HTMLDivElement;` — if the element doesn't actually exist and getElementById returns null, what happens?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
const el = document.getElementById("app") as HTMLDivElement;
// "as" — TypeScript stops checking; if you're wrong, it's a runtime bug, not a compile error
as (a type assertion) tells the compiler "I know more than you do here, trust me" — it performs no runtime check. If getElementById actually returns null (element not found), el is still typed HTMLDivElement, and the mistake only surfaces later as a runtime crash, not a compile error.
satisfies checks, without wideningconst palette = {
red: [255, 0, 0],
green: "#00ff00", // ❌ satisfies catches this — string isn't number[]
} satisfies Record<string, number[]>;
palette.red[0]; // ✅ still typed as number, not widened to Record's generic value type
satisfies validates the expression against a type — real compile-time checking, unlike as — but then keeps the narrower, actually-inferred type for the variable, instead of widening it to the asserted/checked type the way a type annotation (: Record<string, number[]>) would.
const el = document.getElementById('x') as HTMLInputElement — "I know more than you do." No runtime check happens.
as is not a runtime cast, despite looking like one. Nothing about value as Type changes value at all — it's purely a compiler instruction to treat it as a different type, with zero runtime effect (contrast this with something like Number(value), which really does convert).as can't jump between completely unrelated types directly — TypeScript requires the assertion to be at least somewhat plausible (one type must overlap with the other); genuinely unrelated conversions need the as unknown as T double-assertion escape hatch.satisfies was added specifically to fix the annotation-widening problem — before it existed, giving an object an explicit type annotation to get validation meant losing the precise literal types on its properties; satisfies gets validation without that tradeoff."What's the difference between as T, a type annotation : T, and satisfies T?" is a sharp, modern TypeScript question — satisfies is recent enough that explaining exactly what problem it solves (validation without losing precision) is a strong, current signal.