TypeScript Interview Questions and Answers
Types, generics, narrowing, utility and conditional types, configuration and typing React.
225 questions for TypeScript interviews with answers and explanations - Junior, Middle and Senior levels. Sample questions, online quizzes and coding tasks.
- Generics
- Narrowing
- Utility types
- tsconfig
Questions by level
Junior
Core concepts and syntax · 50 questions
Middle
Practice, nuances and optimization · 50 questions
Senior
Architecture, internals, edge cases · 50 questions
Sample questions
A few questions from each level with the correct answer and an explanation.
TypeScript · Junior
- What is TypeScript?
Correct answer: A superset of JavaScript with static typing that compiles to JS
Any valid JS is almost always valid TS. Types are checked at compile time and then erased: plain JavaScript runs at runtime, and there are no type checks there. That's why external data (APIs, forms) is still validated at runtime - e.g. with Zod.
- Does TypeScript check types while the program is running?
Correct answer: No: types are erased at compile time; plain JS runs at runtime
TypeScript is a development-time tool. If an API returns
nullinstead of an object, types won't save you. For runtime checks, usetypeof/instanceofand schema libraries (Zod, Valibot), from which you can also infer TS types. - How does
unknowndiffer fromany?Correct answer: You can't do anything with
unknownwithout narrowing, whileanydisables checksanyturns typing off and "infects" everything it touches.unknownis the safe counterpart: the value can be anything, but you can use it only after a check (typeof x === 'string'). For data fromJSON.parseandcatch (e),unknownis the right choice. - What does the
nevertype mean?Correct answer: The type of a value that can't exist: the function never returns control
neveris the empty type. It's returned by functions that always throw or loop forever. It also appears when a union is fully narrowed - exhaustiveswitchchecks are built on this.voidmeans the function finishes but its result isn't used.
TypeScript · Middle
- What does
<T extends { id: string }>mean in a generic?Correct answer: A constraint:
Tmust have at least anid: stringpropertyA constraint lets you safely access
item.idinside the function while keeping the full typeTin the result. You can pass any object with a suitableidand other fields. Classes and inheritance have nothing to do with it. - How do you type
getProp(obj, key)so the result depends on the key?Correct answer:
function getProp<T, K extends keyof T>(obj: T, key: K): T[K]K extends keyof Tallows only existing keys, and the indexed accessT[K]gives the exact value type:getProp(user, 'age')→number. Theanyversion loses typing, andstringlets typos through. - What does the conditional type
T extends string ? 'text' : 'other'do?Correct answer: Picks one of the types depending on whether
Tis assignable tostringConditional types are a type-level "ternary". Together with
infer, they let you extract parts of types. Applied to a union, they distribute over each member (distributive conditional types). - What does
inferdo intype ElementType<T> = T extends (infer U)[] ? U : never?Correct answer: Declares a type variable
Uthat TS infers from matching the patterninferis used only in theextendspart of a conditional type: TS matchesTagainst the pattern and "captures" the needed part.ElementType<string[]>→string. That's howReturnType,ParametersandAwaitedwork.
TypeScript · Senior
- With
strictFunctionTypes, can you assign(x: Dog) => voidto a variable of type(x: Animal) => void?Correct answer: No: function parameters are checked contravariantly
The variable promises to accept any
Animal, but the function can only handleDog- a call withCatwould break. So subtyping by parameter goes the opposite way:(x: Animal) => voidcan be assigned where(x: Dog) => voidis expected, but not vice versa. - Why doesn't
strictFunctionTypesapply to a method declared ashandle(x: Dog): void?Correct answer: Method-syntax parameters are checked bivariantly for compatibility
Method bivariance was kept so that many built-in types (e.g.
Array<T>) stay compatible. If you declare a function propertyhandle: (x: Dog) => voidinstead, the check is strict. That's why property syntax is often preferred for callbacks in interfaces. - What is
ToArray<string | number>iftype ToArray<T> = T extends any ? T[] : never?Correct answer:
string[] | number[]A conditional type over a "naked" type parameter distributes over a union: the condition is applied to each member separately. This is a distributive conditional type -
ExcludeandExtractare built on it. - How do you turn off a conditional type's distribution over a union?
Correct answer: Wrap both sides in a tuple:
[T] extends [U] ? X : YDistribution happens only when the checked type is a "naked" parameter. The tuple
[T]makes it composite, so the union is checked as a whole:[string | number] extends [string]→ false. There's no compiler setting for this.
Combined quizzes with this topic
Questions from several topics at once - just like an interview for a specific role.
Coding tasks
Write your solution right in the browser, and tests check it instantly. Interview classics: debounce, throttle, deepClone, Promise.all, EventEmitter, an LRU cache and more.
Open tasks →