All jobs / Frontend / web developer

TypeScript interview questions

TypeScript questions a Frontend / web developer can be asked, from first job to senior. Open one to see the strongest answer and why it works.

  1. What is the difference between an interface and a type alias in TypeScript, and how do you choose?

    The strongest answer: Both describe object shapes. Interfaces can be extended and merged by declaration; type aliases can also name unions, tuples and primitives. I follow the team convention and use type where a union is needed

    Why it works: Right — for object shapes they overlap; unions and tuples need type, declaration merging needs interface. Consistency matters more than the pick.

    • Overlap for objects; differ at the edges.
    • Unions and tuples: type alias.
    • Extension and declaration merging: interface.
    • Be consistent within the codebase.
  2. You write a helper that returns the first item of any array. How do you type it so callers keep their element type?

    The strongest answer: Make it generic — first<T>(items: T[]): T | undefined — so the element type flows from the argument to the result, and an empty array is accounted for

    Why it works: Exactly — a type parameter links input to output, and undefined in the return type is honest about empty arrays.

    • Let the type flow through.
    • Add a type parameter T.
    • Use T in argument and result.
    • Include undefined for the empty case.
  3. JSON.parse gives unknown (or you treat it that way). How do you use user.id?

    The strongest answer: Narrow with a type guard or a schema (zod or similar) before you read user.id

    Why it works: Unknown is a stop sign: prove the shape, then use the fields.

    • Prove the payload before you touch it.
    • Keep parse results unknown.
    • Guard or schema-validate.
    • Then read user.id on the narrowed type.
  4. There is a User type with ten fields. The edit-profile form sends only some of them, all optional, and never the id.

    How do you type the form payload?

    The strongest answer: Derive it from User with utility types — Omit the id, then Partial, or Pick just the editable fields — so the payload type follows User when it changes

    Why it works: Right — Pick, Omit and Partial derive the shape from one source, so a renamed field breaks the form at compile time, not in production.

    • Derive, don’t duplicate.
    • Omit what is never sent.
    • Partial for optional edits.
    • One source type, many views.
  5. A request is { status: 'loading' } | { status: 'ok', data: T } | { status: 'err', message }. How do you render data?

    The strongest answer: Narrow on status (a discriminated union) so data exists only in the ok branch

    Why it works: Discriminated unions are the TypeScript interview: the compiler only gives you data after the tag matches.

    • Tag the state, then switch.
    • Use a shared status field.
    • Render data only in the ok case.
    • Don't assert or cast away loading.
  6. For a fixed set of order statuses, do you use a TypeScript enum or a union of string literals? Argue it.

    The strongest answer: Default to a string-literal union, or an as-const object when values are needed at runtime: it matches the API’s strings and narrows cleanly, while an enum emits extra runtime code

    Why it works: Exactly — the union is zero-runtime and lines up with the wire format. Enums are not wrong, but you should be able to say what they cost.

    • Know what each choice emits.
    • Union: erased, matches JSON strings.
    • Enum: runtime object, TypeScript-only construct.
    • Use exhaustive switches on either.
  7. A 300-file frontend was written with strict mode off. Turning it on reports thousands of errors, and the team is split on whether it is worth it.

    How do you lead this?

    The strongest answer: Make it incremental: strict for new and touched files first, stop new any with lint, fix module by module starting where bugs hurt most, track the remaining count, and set a date to flip the global flag

    Why it works: Right — a ratchet: no new debt, steady pay-down, visible progress, and an end date. The business keeps shipping while the floor rises.

    • Ratchet, don’t big-bang.
    • Strict for new and touched code.
    • Block new any with lint.
    • Track the count; set a finish date.