Interview Q&A / TypeScript

INTERVIEW Q&A · 47 QUESTIONS

TypeScript interview questions

Types, interfaces, generics and safe patterns for real codebases.

  1. Should you use an enum or a union of string literals in TypeScript?

    Both describe a fixed set of allowed values. An enum creates a real JavaScript object at runtime and its members must be referenced by name. A union of string literals like "admin" | "user" exists only at compile time, adds no code, and accepts plain strings. Many teams now prefer unions, or an as const object when they also need runtime values.

    IntermediateIn-depth4 min read
  2. What is type narrowing in TypeScript, and how do type guards work?

    Narrowing is how TypeScript refines a broad type, like string | number, to a more specific one inside a block after a check. Type guards are those checks, such as typeof, instanceof, the in operator, equality checks on a shared field, and custom functions that return a type predicate like value is User.

    IntermediateIn-depth3 min read
  3. How do you filter null values out of an array so TypeScript knows the result has no nulls?

    Pass a type predicate to filter: arr.filter((x): x is string => x !== null). Plain filter(x => x !== null) returns (string | null)[] in older TypeScript, because the compiler does not infer the narrowing from the callback.

    IntermediateQuick answer1 min read
  4. How do you get the element type of an array type or a tuple in TypeScript?

    Use an indexed access with number: T[number]. For string[] it gives string, and for a readonly tuple declared as const it gives the union of its member literals.

    IntermediateQuick answer1 min read
  5. How do you remove readonly or optional from every property using mapped type modifiers?

    Prefix the modifier with a minus sign inside a mapped type: -readonly removes readonly and -? removes optionality. A plus sign, or none, adds it. Required<T> is exactly { [K in keyof T]-?: T[K] }.

    IntermediateQuick answer1 min read
  6. How do you write a generic arrow function in a .tsx file?

    In .tsx, <T>(x: T) => x is parsed as a JSX tag and fails. Write <T,>(x: T) => x with a trailing comma, or <T extends unknown>, or use a regular function declaration instead.

    IntermediateQuick answer1 min read
  7. How do you write a type-safe getProperty function with keyof?

    Use two type parameters: function getProperty<T, K extends keyof T>(obj: T, key: K): T[K]. K is limited to real keys of T, and the return type is exactly that property's type, so no casts or any are needed.

    IntermediateQuick answer1 min read
  8. How do you write a user-defined type guard with the is keyword?

    Declare a function whose return type is a type predicate, like (x: unknown): x is User. When it returns true, TypeScript treats x as User in that branch. The compiler trusts your logic, so the check inside must be correct.

    IntermediateQuick answer1 min read
  9. How does Record with a union of keys help catch missing cases?

    Record<Union, V> requires an entry for every member of the union. Adding a new member later makes every object typed with it fail until the new key is added, so you cannot forget a case.

    IntermediateQuick answer1 min read
  10. What does keyof typeof do, and why is it used with objects?

    typeof obj gives the type of the object and keyof turns its keys into a union, so keyof typeof obj is the union of the object's key names. It lets one object be the single source for both runtime values and key types.

    IntermediateQuick answer1 min read
  11. What does the Parameters utility type do?

    Parameters<typeof fn> returns the parameter types of a function as a tuple, for example [string, number]. You can index it, like Parameters<typeof fn>[0], to get one argument's type, which helps when wrapping functions.

    IntermediateQuick answer1 min read
  12. What is a conditional type in TypeScript?

    A conditional type picks one of two types based on a check: T extends U ? X : Y. If T is assignable to U the result is X, otherwise Y. It lets types make decisions, like an if statement for types.

    IntermediateQuick answer1 min read
  13. What is a default type parameter in a generic, and when is it useful?

    A default like <T = string> is used when the caller gives no type argument and TypeScript cannot infer one. It keeps simple usage short while still allowing a custom type when needed.

    IntermediateQuick answer1 min read
  14. What is a mapped type in TypeScript?

    A mapped type builds a new object type by looping over the keys of another type with the syntax { [K in keyof T]: ... }. Partial, Readonly and Pick are all mapped types written this way.

    IntermediateQuick answer1 min read
  15. What is the Awaited utility type for?

    Awaited<T> gives the type you get after awaiting a promise, unwrapping nested promises too. Awaited<Promise<string>> is string. It is mostly used with ReturnType to get the resolved type of an async function.

    IntermediateQuick answer1 min read
  16. What is the difference between object, Object and {} in TypeScript?

    object means any non-primitive (arrays, functions, plain objects). {} means any value that is not null or undefined, including primitives like 5. Object is the wrapper interface with toString and friends and behaves almost like {}. Prefer real shapes or Record instead.

    IntermediateQuick answer1 min read
  17. When does TypeScript infer generic type arguments, and when must you pass them yourself?

    TypeScript infers type arguments from the values you pass. You must write them explicitly when no argument carries the type, such as an empty collection or a function whose type appears only in the return, or when you want a wider type than the inferred one.

    IntermediateQuick answer1 min read
  18. When should you use a generic instead of a union type for a function parameter?

    Use a generic when the output type must follow the input type, such as returning the same kind you received. Use a union when the function accepts several kinds and the result does not depend on which one it was.

    IntermediateQuick answer1 min read
  19. Why does TypeScript infer a literal type for const but a wider type for let?

    A const can never change, so its type is the exact value, like "IN". A let can be reassigned, so TypeScript widens it to the general type, string. This is called literal widening and it explains many surprising errors with object properties.

    IntermediateQuick answer1 min read
  20. Why does TypeScript sometimes forget a narrowed type inside a callback?

    Narrowing holds only while the compiler can be sure the variable has not changed. A let variable captured by a callback might be reassigned before the callback runs, so TypeScript resets it to the declared type. Use const or copy the value to a const first.

    IntermediateQuick answer1 min read