Skip to content

TypeScript Interview Questions

TypeScript interviews probe static typing, inference, generics, and how types compile away while shaping runtime-safe APIs.

TypeScript Interview Overview

Expect questions on basic types, interfaces vs type aliases, unions, narrowing, and tsconfig strict flags. Show you understand that TypeScript is a compile-time layer over JavaScript and that types are erased at runtime unless you emit decorators or use const enums carefully.

Senior rounds cover generics constraints, conditional and mapped types, module augmentation, and migration strategy from JavaScript. Be ready to discuss when to reach for unknown over any, how satisfies differs from as, and how structural typing affects API design.

TypeScript Interview Cheatsheet

Quick answers you can expand in a real interview.

Topic Short answer
Strictest safety flag strict: true in tsconfig.json
Unknown vs any unknown requires narrowing before use
Readonly arrays readonly T[] or ReadonlyArray<T>
Narrow union typeof, in, discriminant property
Pick/Omit utility Shape subsets of object types
Satisfies operator Validate shape without widening literals

15 TypeScript Interview Questions with Answers

Use the short version first, then offer trade-offs if the interviewer wants depth.

1. What is TypeScript and what problem does it solve?

TypeScript is a typed superset of JavaScript that adds optional static types, interfaces, enums, and compile-time checking. It catches category errors before runtime, improves IDE autocomplete and refactoring, and documents contracts in large codebases. Output is plain JavaScript via tsc or bundlers.

2. Difference between interface and type alias?

Both describe object shapes and can be extended. Interfaces support declaration merging (multiple declarations merge), which is useful for augmenting third-party modules. Type aliases can represent unions, tuples, primitives, and mapped types interfaces cannot express as cleanly. Prefer interfaces for public object APIs; types for unions and utilities.

3. What is type inference?

The compiler deduces types when you omit annotations—const x = 1 yields number literal or number depending on context. Function return types are inferred from return statements. Lean on inference for locals; annotate exported function parameters and public APIs for stable contracts.

4. Explain structural typing in TypeScript.

TypeScript uses structural (duck) typing: if an object has the required properties with compatible types, it matches the type regardless of name. Two interfaces with identical shapes are assignable to each other. This differs from nominal typing in languages like Java and affects how you design API boundaries.

5. What is the difference between any and unknown?

any disables type checking for that value—you can call anything on it. unknown is the type-safe top type: you must narrow or assert before use. Prefer unknown for external data (JSON.parse results) and reserve any only for gradual migration with eslint rules limiting spread.

6. How does type narrowing work?

Control flow analysis refines types after checks: typeof x === "string", x instanceof Date, "id" in obj, or discriminated unions with a kind/tag field. Switch statements and early returns help the compiler understand which branch you are in.

7. What are generics and why use them?

Generics parameterize types so functions and classes work across types while staying type-safe: function identity<T>(value: T): T. Constraints like T extends { id: string } limit acceptable types. They avoid duplication and any while preserving relationships between inputs and outputs.

8. Difference between enum and union of string literals?

String literal unions like type Status = "idle" | "loading" have no runtime artifact and tree-shake cleanly. Enums generate JavaScript objects and can surprise you with reverse mappings for numeric enums. Modern codebases often prefer as const objects or unions unless interop requires enums.

9. What does strict mode enable in tsconfig?

strict turns on strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitAny, noImplicitThis, and alwaysStrict. It catches null/undefined bugs, loose function types, and implicit any. Teams enabling strict incrementally often use strictNullChecks first.

10. Explain the satisfies operator.

const config = { host: "api.example.com", port: 443 } satisfies ServerConfig validates against ServerConfig without widening literal types to string/number. Unlike as ServerConfig, satisfies preserves narrow literals for autocomplete while still erroring on missing or wrong keys.

11. What are utility types Pick, Omit, Partial, and Record?

Pick<T, K> selects keys; Omit<T, K> removes them. Partial<T> makes all properties optional—handy for update DTOs. Record<K, V> builds an object type with keys K and values V. These compose for API layers without duplicating interface definitions.

12. How do you type a function that might throw vs return?

TypeScript return types describe successful returns only; thrown errors are not in the union unless you model Result types manually. For expected failures, return { ok: true, data } | { ok: false, error } or use libraries like neverthrow. Document thrown exceptions in JSDoc for consumers.

13. What is declaration merging and module augmentation?

Interfaces with the same name in the same scope merge declarations—useful for extending Express Request or global Window. Module augmentation adds types to imported modules: declare module "express-serve-static-core" { interface Request { user?: User } }.

14. How would you migrate a large JavaScript codebase to TypeScript?

Enable allowJs and checkJs, add a tsconfig with incremental strictness, rename files gradually, and type boundaries first (API modules, shared utils). Use unknown for external input, avoid mass any, and enforce noImplicitAny in CI once coverage is sufficient. @types packages cover many libraries.

15. What are conditional types and when are they useful?

Conditional types choose one type or another based on a condition: T extends U ? X : Y. They power advanced utilities like Exclude, Extract, and infer in template literal types. Use them in library typings—not everyday app code—when inference must depend on generic parameters.

Common Mistakes

  • Using any everywhere to silence the compiler during migration.
  • Assuming runtime validation exists because TypeScript compiled.
  • Overusing type assertions (as) instead of proper narrowing.
  • Ignoring strictNullChecks and fighting undefined at runtime.

Key Takeaways

  • Types are compile-time only—validate external data at runtime.
  • Prefer unknown, generics, and narrowing over any and assertions.
  • Know interface vs type and when declaration merging helps.
  • Explain migration and strict mode as team scalability choices.

Pro Tip

When asked a typing puzzle, talk through inference out loud—interviewers care about reasoning, not memorizing utility type syntax.