What this round is for
TypeScript interviews reward people who know what the language does not do. The types are erased, so nothing is checked at run time, and the most common serious mistake is trusting an annotation on data that came from outside the program.
Expect the round to move from syntax to narrowing to generics, and then to a question about validating an API response - which is where the theory meets the part that actually breaks.
The questions
Answer each one out loud before you open it. An answer you have read is not an answer you can
give under pressure, which is the only kind that counts.
Q1
What problem does TypeScript solve?
Show the answer
Hide the answer
It makes the assumptions your code already relies on explicit, so a compiler can check they are consistent.
It does not make a running program safe - the types are erased before execution. What it catches is two parts of a codebase disagreeing about the shape of data, which is the expensive bug in a large project.
What it is really testing.
Whether you overstate it. A candidate who says it prevents run-time errors has misunderstood what erasure means.
Q2
What happens to types at run time?
Show the answer
Hide the answer
Nothing - they are erased during compilation and the output is plain JavaScript.
So you cannot check instanceof against an interface, and an annotation on an API response is an assertion rather than a verification. Data crossing a boundary needs a real run-time check.
What it is really testing.
Whether you know annotations on fetched data are unverified. This is the most consequential misunderstanding in the language.
Q3
What is the difference between interface and type?
Show the answer
Hide the answer
Both describe shapes; interface can be reopened and merged, type can express unions, intersections and mapped types.
For plain object shapes they are interchangeable. The practical convention is interface for things others extend, type for everything else - and consistency matters more than the choice.
What it is really testing.
Whether you know declaration merging exists. It explains some surprising behaviour with library types.
Q4
What is any and why is it dangerous?
Show the answer
Hide the answer
It turns off checking for that value, and anything derived from it is also any.
One annotation can silently disable checking across a whole call path with no warning. noImplicitAny is the setting that finds the ones you did not write deliberately.
What it is really testing.
Whether you know it is contagious. That property is what makes it worse than it looks.
Q5
What is unknown and when would you use it?
Show the answer
Hide the answer
It also means the type is not known, but it refuses any operation until you narrow it.
It is the honest alternative to any for genuinely dynamic data - a parsed JSON body, a caught error. The compiler then prompts you to write the validation you were skipping.
What it is really testing.
Whether you reach for it instead of any. It is a strong signal of someone who has used the language properly.
Q6
What does strictNullChecks do?
Show the answer
Hide the answer
It stops null and undefined being assignable to every type, so a nullable value must be declared and handled.
Without it the type system is lying about the most common run-time error in JavaScript. It is the setting that turns TypeScript from autocomplete into something that catches bugs.
What it is really testing.
Whether you have it on. Projects without it often conclude TypeScript catches nothing.
Q7
What is a discriminated union?
Show the answer
Hide the answer
A union of object types sharing a literal field that identifies which case you have.
Checking that field narrows the type, so the compiler knows which other fields exist. It makes invalid combinations unrepresentable, which is stronger than a convention about checking the right one.
What it is really testing.
Whether you can model a state machine with it. This is the most valuable pattern in the language.
Q8
What is type narrowing?
Show the answer
Hide the answer
The compiler tracking which of a union's cases you are in, based on ordinary checks.
typeof, instanceof, the in operator, truthiness and equality against literals all narrow. You are not learning a new query syntax - you write the checks you would have written anyway.
What it is really testing.
Whether you know it works from normal JavaScript. Candidates often think it needs special syntax.
Q9
What is a type guard?
Show the answer
Hide the answer
A function whose return type is a type predicate, telling the compiler what the value is if it returns true.
It is how you make a run-time check inform the type system. Without one, the compiler has no way to know your validation proved anything.
What it is really testing.
Whether you can write one. It is the bridge between run-time and compile-time safety.
Q10
What are generics for?
Show the answer
Hide the answer
Preserving the relationship between input and output types instead of discarding it.
A function returning the first element of an array of T returns T, not any. Whenever you reach for any because a function is reused across types, a generic is usually the answer.
What it is really testing.
Whether you reach for them to avoid any rather than to show off.
Q11
What is a generic constraint?
Show the answer
Hide the answer
extends on a type parameter, restricting what may be passed and what you may do with it.
Without a constraint the compiler knows nothing about T, so you cannot access properties. Constraining to an object with an id lets you use that id while staying generic.
What it is really testing.
Whether you know why an unconstrained T is almost unusable.
Q12
What are Partial, Pick, Omit and Record for?
Show the answer
Hide the answer
Deriving one type from another so the two cannot drift apart.
Writing a second interface by hand means adding a field to the first will silently fail to update it. Omit<User, 'passwordHash'> stays correct forever.
What it is really testing.
Whether you reach for derived types instead of hand-copying shapes.
Q13
What does Record<K, V> give you that an index signature does not?
Show the answer
Hide the answer
Exhaustiveness - if K is a union of literals, every key must be present.
A Record keyed by a status union fails to compile when a new status is added and its entry is missing. An index signature would accept anything and silently return undefined.
What it is really testing.
Whether you value compile errors for forgotten cases over silent undefined.
Q14
What are literal types?
Show the answer
Hide the answer
Types whose value is a specific string, number or boolean rather than the whole primitive.
They are what makes a discriminated union work and what turns a stringly-typed parameter into one the compiler can check. Combined with a union they replace most enums.
What it is really testing.
Whether you connect them to unions. On their own they look pointless.
Q15
Should you use enum or a union of literals?
Show the answer
Hide the answer
A union of string literals in most cases - it is simpler and erases cleanly.
Numeric enums allow values outside the declared set, and non-const enums generate run-time code, which surprises people expecting erasure. const enums avoid that but have their own caveats.
What it is really testing.
Whether you know enums are not fully erased. That surprises people expecting zero output.
Q16
What does as do, and when is it dangerous?
Show the answer
Hide the answer
It asserts a type to the compiler without any check.
It is appropriate where you genuinely know more than the compiler, such as after a validation it cannot see. It is dangerous as a way to silence an error, because the mismatch is still there at run time.
What it is really testing.
Whether you distinguish a justified assertion from silencing the compiler.
Q17
What is the difference between as const and a normal declaration?
Show the answer
Hide the answer
as const makes the value deeply readonly and infers the narrowest literal types.
An array becomes a readonly tuple of literals rather than string[], which is what lets you derive a union type from a list of values.
What it is really testing.
Whether you know how to derive a union from an array of values.
Q18
What are mapped types?
Show the answer
Hide the answer
Types built by transforming each property of another type.
They are how Partial and Readonly are defined. Writing your own is occasionally useful and frequently a sign that the problem would be clearer with a plain union.
What it is really testing.
Whether you recognise them in library types rather than writing your own.
Q19
What is a conditional type?
Show the answer
Hide the answer
A type that chooses between two results based on whether one type extends another.
They power the utility types and library inference. In application code they are usually more cleverness than the readers of that code will thank you for.
What it is really testing.
Whether you can read one. Writing them is rarely needed in application code.
Q20
What does infer do?
Show the answer
Hide the answer
It captures a type from within another type during a conditional type.
It is how ReturnType and Awaited are written. Recognising it matters more than writing it, because it appears constantly in library definitions.
What it is really testing.
Whether you have read a library's type definitions. It appears constantly there.
Q21
What is structural typing?
Show the answer
Hide the answer
Compatibility is decided by shape, not by name or declared inheritance.
An object with the right properties satisfies an interface without declaring that it does. That is why TypeScript feels closer to duck typing than to nominal languages like Java or C#.
What it is really testing.
Whether you know it is structural. People from Java or C# often assume otherwise.
Q22
What is excess property checking?
Show the answer
Hide the answer
Object literals assigned directly to a typed target are rejected if they have extra properties.
It only applies to fresh literals, so assigning via a variable first bypasses it. That inconsistency surprises people, and it exists to catch typo'd property names.
What it is really testing.
Whether you know the literal-only rule, which is why assigning via a variable behaves differently.
Q23
What is the difference between unknown and never?
Show the answer
Hide the answer
unknown is the top type - anything is assignable to it. never is the bottom type - nothing is.
never appears as the return type of a function that always throws, and as the type of an impossible branch. Seeing it in an error usually means your narrowing excluded every case.
What it is really testing.
Whether you know what never means when it appears in an error message.
Q24
How would you ensure a switch handles every case?
Show the answer
Hide the answer
Assign the value to a never in the default branch - an unhandled case then fails to compile.
It turns adding a new union member into a compile error listing everywhere that needs updating, which is the main argument for unions in a long-lived codebase.
What it is really testing.
Whether you know the exhaustiveness trick. It is the main long-term benefit of unions.
Q25
What does the non-null assertion operator do?
Show the answer
Hide the answer
The exclamation mark tells the compiler a value is not null or undefined, with no check.
It is an assertion like as and carries the same risk. Reaching for it frequently means the types are wrong somewhere upstream rather than at the point of use.
What it is really testing.
Whether you treat it as a last resort rather than a convenience.
Q26
How do you type an async function?
Show the answer
Hide the answer
Annotate the return as Promise<T>; await unwraps it.
An async function always returns a promise, so declaring the return as T rather than Promise<T> is an error. Awaited<T> exists for unwrapping nested cases.
What it is really testing.
Whether you know an async function cannot declare a non-promise return.
Q27
What is declaration merging?
Show the answer
Hide the answer
Two declarations of the same interface or namespace combine into one.
It is how you extend a library's types from your own code, and occasionally how two files contribute to one interface by accident, which is confusing to debug.
What it is really testing.
Whether you know it can happen accidentally as well as deliberately.
Q28
What is a .d.ts file?
Show the answer
Hide the answer
A declaration file containing types with no implementation.
It describes the shape of JavaScript that has no types of its own. DefinitelyTyped publishes these for thousands of packages, which is why untyped libraries are still usable.
What it is really testing.
Whether you know why untyped packages are still usable.
Q29
What does tsconfig strict actually turn on?
Show the answer
Hide the answer
About eight checks including strictNullChecks, noImplicitAny and strictFunctionTypes.
Two people can have identical code with very different levels of checking depending on this file. Enabling it on a new project costs nothing; enabling it later is a project.
What it is really testing.
Whether you have looked at the config rather than inheriting one.
Q30
What is noUncheckedIndexedAccess?
Show the answer
Hide the answer
It makes indexing an array or record return T | undefined rather than T.
It is honest - index access genuinely can miss - and it catches a real class of bug at the cost of extra checks. Most projects leave it off and are slightly lying to themselves.
What it is really testing.
Whether you know index access is unchecked by default. Most people do not.
Q31
How do you type a function that takes several shapes?
Show the answer
Hide the answer
Overload signatures, or a union parameter with narrowing inside.
Overloads give callers precise types per shape at the cost of a more complex declaration. A union is simpler and usually sufficient.
What it is really testing.
Whether you weigh caller clarity against declaration complexity.
Q32
What is the difference between readonly and const?
Show the answer
Hide the answer
const prevents reassigning a binding; readonly prevents reassigning a property.
Neither makes a value deeply immutable. A readonly array cannot be pushed to through that reference, but another reference without the modifier still can.
What it is really testing.
Whether you know neither is deep. Shallow immutability catches people out.
Q33
How should you type errors in a catch block?
Show the answer
Hide the answer
As unknown, which is the default under strict settings, then narrow before using.
Anything can be thrown in JavaScript, not just Error. Assuming error.message exists is how a catch block throws its own error.
What it is really testing.
Whether you know anything can be thrown, not only Error objects.
Q34
What is satisfies and why was it added?
Show the answer
Hide the answer
It checks a value against a type without widening the inferred type.
Annotating a config object with its type loses the literal detail; satisfies validates the shape while keeping the precise inference. It closed a long-standing gap.
What it is really testing.
Whether you keep up with the language. This is recent and solved a real annoyance.
Q35
How do you validate data from an API?
Show the answer
Hide the answer
With a run-time check - a type guard or a schema library that produces both a validator and a type.
An annotation on a fetch result is a promise you made to the compiler. Only a real check makes it true, and schema libraries avoid defining the shape twice.
What it is really testing.
Whether you treat the boundary as the place that needs a real check.
Q36
Where should you annotate and where should you let inference work?
Show the answer
Hide the answer
Annotate boundaries - parameters, exported returns, external data. Let locals infer.
Over-annotating produces noise that is harder to read than the JavaScript it replaced. Explicit return types on exported functions are worth it so drift is reported at the source.
What it is really testing.
Whether you have a rule. Over-annotating is as common a problem as under-annotating.
Q37
How do you read a long TypeScript error?
Show the answer
Hide the answer
Read the last line first - the compiler works outward and ends at the actual mismatch.
Assigning the value to an intermediate variable with an explicit type will often relocate the error to the exact property, which beats a twelve-line structural diff.
What it is really testing.
Whether you have a technique for reading them rather than finding them intimidating.
Q38
What are the costs of adopting TypeScript?
Show the answer
Hide the answer
A build step, compile time, a learning curve, and a temptation to over-engineer types.
The return scales with how much data moves between modules and people. On a small script it is overhead; on a codebase several people maintain it is substantial.
What it is really testing.
Whether you can argue against it honestly. Uncritical advocacy is a weaker answer.
Q39
Can TypeScript guarantee your program will not crash?
Show the answer
Hide the answer
No. It narrows a class of bugs at compile time and has no presence at run time.
Logic errors, bad input, network failures and anything from an untyped boundary are all untouched. Treating the compiler as a safety net rather than a thinking tool leads to misplaced confidence.
What it is really testing.
Whether you are calibrated about what it buys. Overconfidence here causes real incidents.
Q40
What is the single highest-value TypeScript habit?
Show the answer
Hide the answer
Turning on strict from the first commit and modelling state as a discriminated union.
Those two decisions between them prevent the null errors and the impossible-state bugs that make up most of what the language is good at catching.
What it is really testing.
Whether you can name a priority. This is often the closing question.