CTCaliberTek
Interview Questions

TypeScript Basics and Types Interview Questions and Answers

15 questions on TypeScript's type system: any, unknown, never, interfaces, unions, narrowing, enums, and structural typing.

  1. 1. What is TypeScript, and why use it instead of JavaScript?

    TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. The type checker catches mistakes before runtime, gives accurate autocomplete and refactoring in editors, and documents how code is meant to be used. Types are erased at compile time, so they add no runtime cost, and they do not replace runtime validation of external data.

  2. 2. What is the difference between any, unknown, and never?

    any turns off type checking for a value, so anything is allowed. unknown is the type-safe alternative: you can assign anything to it, but you must narrow it before using it. never is the type of values that cannot occur, such as the return type of a function that always throws, or the leftover case in an exhaustive check.

    function parse(input: unknown): number {
      if (typeof input === 'string') return Number(input);
      if (typeof input === 'number') return input;
      throw new Error('unsupported input');
    }
  3. 3. What is the difference between interface and type?

    Both describe object shapes and can be extended. Interfaces support declaration merging (declaring the same interface twice combines them) and are the usual choice for object contracts and class implementation. Type aliases can also name unions, intersections, tuples, primitives, and mapped or conditional types, which interfaces cannot. Pick one convention per project.

  4. 4. What are union and intersection types?

    A union (A | B) is a value that is either A or B, and you can only use members common to both until you narrow it. An intersection (A & B) is a value that has all the members of both A and B.

    type Id = string | number;
    type Admin = User & { permissions: string[] };
  5. 5. What is type narrowing?

    TypeScript refines a union to a more specific type inside a branch, using typeof, instanceof, the in operator, equality checks, truthiness, and custom type guards. After a check such as if (typeof value === 'string'), the compiler treats value as a string within that branch.

  6. 6. What are discriminated unions?

    A union of object types that share a literal property (the discriminant). Checking that property narrows the whole object, and a switch can be checked for exhaustiveness.

    type Shape =
      | { kind: 'circle'; radius: number }
      | { kind: 'square'; size: number };
    
    function area(shape: Shape): number {
      switch (shape.kind) {
        case 'circle': return Math.PI * shape.radius ** 2;
        case 'square': return shape.size ** 2;
      }
    }
  7. 7. What is a type guard? How do you write a custom one?

    A type guard is an expression that narrows a type. A custom guard is a function whose return type is a type predicate.

    function isString(value: unknown): value is string {
      return typeof value === 'string';
    }

    The compiler trusts the predicate, so the check inside must really match the type you declare.

  8. 8. What is structural typing?

    TypeScript compares types by their shape, not by their name. If an object has all the properties a type requires, it is assignable to it, even if it was never declared to implement it. This is why plain object literals can be passed where an interface is expected. Fresh object literals are additionally checked for extra properties.

  9. 9. What are enums, and are there alternatives?

    An enum defines a set of named constants. Numeric enums also create a reverse mapping at runtime, and enums generate real JavaScript code. A common alternative is a union of string literals, or an object declared as const, which adds no extra runtime structure and works well with type inference.

    const Role = { Admin: 'admin', User: 'user' } as const;
    type Role = typeof Role[keyof typeof Role];   // 'admin' | 'user'
  10. 10. What does as const do?

    It tells TypeScript to infer the narrowest possible type: literal types instead of widened ones, readonly arrays become tuples, and object properties become readonly. It is useful for configuration objects and for deriving union types from values.

  11. 11. What are optional properties, readonly, and index signatures?

    A question mark makes a property optional (it may be missing or undefined). readonly prevents reassignment after creation. An index signature describes objects with arbitrary keys, such as { [key: string]: number }. With noUncheckedIndexedAccess enabled, reading by index also includes undefined, which is safer.

  12. 12. What is the difference between a type assertion and a type cast?

    TypeScript has assertions (value as Type), which only tell the compiler to treat a value as that type. Nothing changes at runtime and no checking is done, so a wrong assertion causes runtime errors. A cast in other languages converts the value. Prefer narrowing and validation over assertions, and avoid double assertions through unknown.

  13. 13. What is the non-null assertion operator?

    A trailing exclamation mark (value!) tells the compiler that a value is not null or undefined. It suppresses the check without adding one at runtime, so it can hide real bugs. Prefer an if check, optional chaining, or a clear error.

  14. 14. What are tuples?

    A tuple is an array with a fixed length where each position has its own type, such as [string, number]. They can include optional and rest elements and labels, which makes them good for returning multiple values, like the useState pair in React.

  15. 15. How does TypeScript infer types, and when should you annotate explicitly?

    TypeScript infers types from initial values, return statements, and context, so local variables rarely need annotations. Annotate function parameters, exported function return types, and public APIs, where the annotation acts as documentation and prevents accidental changes to the contract.

Interview Tips

  • Explain the reasoning behind your type choices: why unknown instead of any, or a union instead of an enum.
  • Know that types disappear at runtime, and be ready to say how you would validate API data.
  • Practice writing a type guard and a discriminated union on a whiteboard.