TypeScript Interview Questions — Practice with Real Quiz Questions

Reviewed by Mark Dickie · Last updated

TypeScript is a statically typed superset of JavaScript that compiles to plain JavaScript, adding optional type annotations, interfaces, and compile-time error checking. For interviews, you should know the type system (primitives, unions, intersections, literal types), generics and constraints, type narrowing (typeof, instanceof, in, user-defined type guards), utility types (Partial, Pick, Omit, Record, ReturnType), and the structural typing model that distinguishes TypeScript from nominally typed languages like Java or C#. Expect questions on configuration options like strict mode, tsconfig.json settings, declaration files (.d.ts), and the differences between interface and type aliases.

TopicWhat to study
GenericsConstraints with extends, default type parameters, conditional types
Type narrowingDiscriminated unions, in operator, custom type guards
Utility typesPartial<T>, Omit<T,K>, Record<K,V>, ReturnType<T>
Structural typingShape compatibility vs. nominal typing
tsconfigstrict, noImplicitAny, target, moduleResolution
Declaration mergingHow interfaces with the same name combine

What does a TypeScript interview typically test?

Most TypeScript interviews focus on practical type-level problem solving rather than trivia. You may be asked to write a generic function, build a utility type from scratch, or debug why the compiler rejects an assignment that looks correct at first glance. Senior-level roles go further into conditional types, mapped types, template literal types, and variance. The interview usually mixes whiteboard or live-coding with conceptual questions about why a particular type annotation is needed.

What is the difference between interface and type in TypeScript?

Both can describe object shapes, and in most cases they are interchangeable. Key differences:

  1. Interfaces support declaration merging — declaring the same interface name twice merges their members. Type aliases do not.
  2. Type aliases can represent unions, intersections, tuples, and primitive aliases. Interfaces are limited to object and function shapes.
  3. Interfaces can be extended with extends, and types can be combined with the & intersection operator. Both approaches work for composition.
  4. Error messages tend to read more cleanly for interfaces in complex scenarios, since the compiler preserves the interface name rather than expanding the alias inline.

How does TypeScript's structural typing affect interview answers?

TypeScript checks shape compatibility, not name identity. An object is assignable to a type if it has all the required properties with matching types — extra properties are allowed in most contexts (except direct object literals, where excess property checking applies). This is the single biggest conceptual difference from languages like Java, and interviewers probe it through questions about assignability, function parameter bivariance, and when to use branding or tagging to recover nominal-like behavior.

Key facts

  • Tarmac has 93 TypeScript interview questions on this topic, 10 of them on this page, at difficulty 2–4 of 5.
  • Tarmac last reviewed these TypeScript interview questions on 18 August 2026.

At a glance

Questions10 shown · 93 in the bank
Difficulty2–4 of 5
FormatsMultiple answer, True / false, Code output, Fill in the blank, Coding exercise, Ordering, Multiple choice, Find the bug, Short answer, Flashcard
Interactive1 run your code against tests, in the app

What you'll review

  1. partial required
  2. primitives
  3. generic functions
  4. pick omit
  5. exhaustiveness
  6. discriminated unions
  7. mapped types

Practice questions

TypeScript/utility-types/partial-required

Which of these are built-in TypeScript utility types?#

Options

Pick every one that applies.

Show answer

Partial<T>, Pick<T, K>, and Readonly<T> are all built-in utility types — but Maybe<T> is not. Maybe comes from some functional-programming libraries rather than TypeScript's standard library, so the compiler does not provide it out of the box.

Why:

Partial, Pick, and Readonly are built in. Maybe is not part of TypeScript's standard library (it comes from some FP libraries).

TypeScript/types-basics/primitives

TypeScript types are erased during compilation and have no presence in the emitted JavaScript.#

Options

Show answer

True. Type annotations, interfaces, and generics are erased during compilation and leave no trace in the emitted JavaScript. That is why you cannot inspect a TypeScript type at runtime — there is nothing left to check, so you must reach for runtime guards like typeof or a validation library instead.

Why:

Type annotations, interfaces, and generics are erased at compile time. That is why you cannot check a type at runtime — there is nothing left to inspect (you must use runtime guards like typeof or a validation library).

TypeScript/generics/generic-functions

What does this log?#

function first<T>(arr: T[]): T | undefined {
  return arr[0];
}
console.log(first([10, 20, 30]));
Show answer
10
Why:

The generic first infers T = number from the argument and returns arr[0], which is 10. Types are erased at runtime; the behaviour is just plain array indexing.

TypeScript/utility-types/pick-omit

_____<User, 'id' | 'name'> keeps only those two keys, while _____<User, 'password'> keeps everything except that one.#

Show answer

**Pick**<User, 'id' | 'name'> keeps only those two keys, while **Omit**<User, 'password'> keeps everything except that one.

Why:

Pick selects a subset of keys; Omit removes them. They're complements — Omit<T, K> is Pick<T, Exclude<keyof T, K>>.

TypeScript/generics/generic-functions

Implement pluck(items, key): given an array of objects and a key, return the array of values at that key. Type it generically so key is constrained to keyof T and the return type is T[K][].#

Starter code

function pluck(items: unknown[], key: string): unknown[] {
  // TODO: generic signature + implementation
  return [];
}

Your solution must pass

  • plucks names

This one is written and run, not read. Solve it in the app and your code is executed against these tests and the hidden ones.

TypeScript/narrowing/exhaustiveness

You're handling a Shape discriminated union exhaustively. Order the steps that make the compiler enforce exhaustiveness.#

Put these in order

Show answer

To make the compiler enforce exhaustiveness, follow these steps in order:

  1. switch (shape.kind) on the discriminant
  2. Handle each known kind in its own case
  3. Assign the value to a never in default

If a new variant is later added without a case, the default assignment to never becomes a compile error.

Why:

Switch on the discriminant, handle each variant, then in default assign the narrowed value to a const _exhaustive: never — if a new variant is added later, that assignment becomes a compile error.

TypeScript/utility-types/partial-required

Which of the following mapped types is exactly equivalent to TypeScript's built-in Partial<T> utility type?#

Options

Show answer

type MyPartial<T> = { [P in keyof T]?: T[P] }; is exactly equivalent to Partial<T>. It maps over every key of T and applies the ? modifier, making each property optional while preserving its original type. Without the ?, the properties stay required; using -? would strip optionality (like Required<T>); and T[P] | undefined alone keeps properties required but unioned with undefined, which is not the same as optional.

Why:

TypeScript's built-in Partial<T> makes all properties optional by mapping over the keys with { [P in keyof T]?: T[P] }. The question asks candidates to reconstruct it manually. Option (a) is correct: it maps every key to an optional property of the same type. Option (b) forgets the ? modifier (that's Readonly<T>-style without readonly). Option (c) uses -? which REMOVES optionality (that's Required<T>). Option (d) maps to T[P] | undefined without the ? modifier, which makes every property required but explicitly typed as T[P] | undefined — subtly different from optional.

TypeScript/utility-types/partial-required

The following DeepPartial<T> utility type is intended to recursively make all properties at every nesting level optional. It has exactly one bug. Identify the buggy line.#

type DeepPartial<T> =
  T extends object
    ? { [P in keyof T]?: DeepPartial<T[P]> }
    : never;
Show answer

The bug is on line 4.

Why:

The code defines DeepPartial<T> which recursively makes all nested properties optional. On line 2, the conditional check should be T extends object (not T extends Object — though that works too, but the real bug is elsewhere). Actually the bug is on line 3: the recursive mapped type uses T[P] instead of DeepPartial<T[P]> for the value — wait, let's read carefully. Line 3 is [P in keyof T]?: DeepPartial<T[P]> — that looks correct. The actual bug is on line 2: T extends object ? { ... } : T — for non-object primitives this is fine. The real bug in this snippet is on line 4: the else branch returns never instead of T. When T is a primitive like string or number, DeepPartial<T> should return T itself, not never. So never on line 4 is the buggy line.

TypeScript/narrowing/discriminated-unions

What is a discriminated union and why is it useful?#

Show answer

A discriminated (tagged) union is a union of object types that share a common literal property — the discriminant. Switching on that property lets TypeScript narrow the value to one exact member, so you can handle each case type-safely and get exhaustiveness checking for free.

Why:

The shared literal field (e.g. type: 'circle' | 'square') is what lets the compiler narrow inside a switch. Adding a never default then enforces that every member is handled.

TypeScript/advanced-types/mapped-types

For type T = { a: 1; b: 2 }, what does keyof T produce?#

Show answer

'a' | 'b' — a union of T's property keys (as string literal types).

Why:

keyof turns an object type's keys into a union of literal types. Combined with generics (<K extends keyof T>) it powers type-safe property access like Pick and get(obj, key).

Sources

The official documentation these questions are checked against:

Related interview questions

The other 83 questions

This page shows 10. A free account opens the rest and marks your answers, which a page of answers can't do. Miss one and it returns a few days later, then a week after that, until you stop missing it.

Start free

Free · the whole bank · 100 graded answers per 30 days · written feedback and job-ad quizzes on the paid plan

What moved, monthly

One email a month when the bulletin comes out: what moved in the markets we track, and the new question topics we published. Confirm your address to join. Unsubscribe any time.