What they're testing
Whether you use TypeScript to catch mistakes or to silence the compiler.
The short answer~30 seconds
any switches type checking off entirely: assignable anywhere, any method call permitted. unknown accepts every value but lets you do nothing with it until you narrow — which is the point. as converts nothing; it just tells the compiler to be quiet, and if you guessed wrong the error surfaces at runtime, precisely where TypeScript was supposed to help.
The long answer
The dangerous property of any is that it SPREADS. One any from a third-party type flows through four layers of functions, and everywhere it passes loses type checking with no warning. noImplicitAny only stops the implicit kind; explicit any needs its own lint rule. unknown, by contrast, stops at the first point of use, which makes it the right type for everything arriving from outside: JSON.parse, request bodies, catch (e).
About as: TypeScript disappears entirely at compile time. No runtime check, no coercion, nothing. const user = data as User where data came off the network is a promise nobody verifies — and the day the API renames a field, you get undefined somewhere deep in the UI. The correct shape is validating at the boundary with Zod or a hand-written type guard, after which the types inside your system are worth trusting.
There is a legitimate exception for as: when you genuinely know more than the compiler, for instance after a check TypeScript can't follow. Then it deserves a comment saying why you're sure. An as with a defensible reason is engineering; an as to make the red squiggle go away is debt.
function handleAny(x: any) {
x.foo.bar(); // biên dịch được, nổ lúc chạy
}
function handleUnknown(x: unknown) {
x.foo.bar(); // lỗi biên dịch — đúng như mong muốn
if (typeof x === 'object' && x !== null && 'foo' in x) {
// ở đây x đã được thu hẹp, dùng an toàn
}
}
// catch luôn là unknown từ TS 4.4 (useUnknownInCatchVariables)
try { risky(); } catch (e) {
const message = e instanceof Error ? e.message : String(e);
}What they'll ask next
?When do you use never?
For things that never happen: a function that never returns, or an unreachable branch. Its most useful application is exhaustiveness checking — assigning the value to never in a switch's default, so adding a new union member breaks the build immediately.
?Do TypeScript types exist at runtime?
No — they're erased entirely. That's why external data must be validated for real at the boundary, and why instanceof works while "checking an interface" doesn't.
These lose points
- Using
anyas a quick fix and leaving it. It fixes nothing; it moves the error to runtime. - Believing
asperforms a runtime check. That misconception causes a lot of production errors.