25 TypeScript interview questions
Structure the TypeScript interview loop around evidence, not syntax recall. Start with a 30-minute screen to confirm recent TypeScript 5.x, Node.js 22/24, browser or framework experience, and communication. Follow with a 60-minute coding/debugging session that uses a small realistic codebase with strict mode, tests, and a failing type/runtime edge case. Add a design interview for API contracts, package boundaries, and evolution of types across services or front ends. For senior candidates, include a leadership interview covering code review standards, migration planning, and incident learning. Close with calibrated references or a take-home review discussion focused on trade-offs, not perfect style.
Junior TypeScript questions
Fundamentals, learning speed and how they debug.
01You inherit a TypeScript file where several values are typed as any to make a feature compile. How would you start making it safer without rewriting the feature?
Listen for: A strong answer starts by finding the boundary where unknown data enters, replacing any with unknown or narrower interfaces, and adding checks close to I/O. They should mention turning on or respecting strict settings, using small commits, relying on tests, and avoiding broad type assertions that only silence the compiler.
Red flag: They say they would cast everything to the expected type and move on.
02A unit test passes, but the page crashes because an API field is sometimes null. What steps would you take to debug and prevent this class of bug?
Listen for: Listen for checking real payloads, reproducing with fixtures, and distinguishing compile-time types from runtime data. Good candidates mention optional chaining only as a short-term guard, then discuss validation with Zod, Valibot, or similar, accurate generated API types, null handling in UI states, and regression tests.
Red flag: They assume TypeScript should have prevented it without considering runtime validation.
03When would you choose a union type over optional properties for modeling UI state?
Listen for: They should describe discriminated unions for states such as idle, loading, loaded, and error, where each state has different required data. Strong answers explain that optional properties can allow impossible combinations, while unions guide rendering logic, improve autocomplete, and make exhaustive checks possible with never or switch statements.
Red flag: They treat unions and optional fields as interchangeable style preferences.
04You see a function returning Promise<void> but it swallows errors in a catch block. What concerns would you raise in review?
Listen for: A good answer identifies hidden failures, misleading success states, and lost observability. They should ask whether the caller needs to react, whether the error should be logged with context, retried, mapped to a user-facing state, or rethrown. They should also consider tests for rejection and failure paths.
Red flag: They think catch blocks are always good because they prevent crashes.
05How do you decide whether a helper belongs in a shared utilities folder or near the feature that uses it?
Listen for: Look for practical judgment: start local until reuse is real, keep domain-specific helpers near the feature, and move stable generic code only when two or more callers need it. They should mention naming, tests, avoiding dependency cycles, and not turning shared folders into dumping grounds.
Red flag: They want every helper shared globally for convenience.
06A colleague says a TypeScript error is wrong and suggests adding as never. How would you respond?
Listen for: They should be willing to investigate the type error, inspect inferred types, simplify the expression, and check whether the model or control flow is wrong. Good answers allow narrow assertions at trusted boundaries with comments, but prefer changing the type model, guards, or function signatures over suppressing the compiler.
Red flag: They accept unsafe assertions whenever they unblock a pull request.
Mid-level TypeScript questions
Independent delivery, trade-offs and code quality.
07You are adding a new public function to an internal TypeScript package used by five services. How do you design the signature so it is useful but hard to misuse?
Listen for: Strong answers discuss explicit input and output types, stable domain names, avoiding boolean flag arguments, and returning typed results or errors instead of throwing unpredictably. They should consider backward compatibility, TSDoc, examples, default behavior, runtime validation at boundaries, and type-level tests or compile-time usage examples.
Red flag: They focus only on making the function generic enough for every possible future use.
08A monorepo build has become slow after adding more TypeScript packages. What would you investigate before changing tools?
Listen for: Listen for measuring first: tsc diagnostics, project references, incremental builds, tsbuildinfo, dependency graph shape, test versus type-check time, and CI cache behavior. They may mention pnpm workspaces, Turborepo, Nx, or Lage, but should focus on package boundaries, unnecessary imports, barrel files, and isolated checks.
Red flag: They immediately propose replacing TypeScript or the monorepo tool without profiling.
09How would you handle types for an HTTP API consumed by both a React app and a Node.js service?
Listen for: A good answer compares OpenAPI generation, tRPC, GraphQL codegen, or shared schema packages depending on ownership and coupling. They should address runtime validation, versioning, error envelopes, authentication context, and generated clients. Strong candidates avoid duplicating handwritten types that can drift from actual responses.
Red flag: They say sharing TypeScript interfaces alone guarantees API correctness.
10A React or Next.js feature has a type-safe data layer but still shows stale or inconsistent data after mutations. What do you inspect?
Listen for: They should move beyond types into cache keys, invalidation, optimistic updates, race conditions, server actions or route handlers, and serialization boundaries. Strong answers mention TanStack Query, SWR, React Server Components, or framework caches where relevant, plus tests that simulate mutation order and network delay.
Red flag: They only look for interface mismatches and ignore caching behavior.
11You need to introduce strictNullChecks to a mature codebase. How would you plan it?
Listen for: Look for incremental migration: enable it per package or with a branch plan, prioritize risky domains, fix boundary types first, and track suppressions. They should mention CI gates, codemods where appropriate, pairing with tests, avoiding mass non-null assertions, and communicating expected churn to the team.
Red flag: They propose adding non-null assertions until the compiler is quiet.
12A library type is too broad and causes weak autocomplete for your use case. How do you improve developer experience without forking the library?
Listen for: A strong answer considers wrapper functions, narrowed local types, module augmentation when appropriate, branded types, satisfies, const assertions, and small adapter layers. They should discuss keeping the runtime behavior unchanged, testing the wrapper, documenting constraints, and avoiding fragile dependence on internal library types.
Red flag: They edit node_modules or copy large vendor types into the app.
13What do you expect from a useful TypeScript code review besides checking if it compiles?
Listen for: Listen for reviewing domain modeling, unsafe assertions, boundary validation, naming, test coverage, error handling, and API evolution. They should comment on maintainability and readability, not personal style. Strong candidates know when to ask for changes, when to suggest, and when to defer to team conventions.
Red flag: They treat review as formatting and compiler-error cleanup only.
Senior TypeScript questions
Judgement, architecture and raising the team's bar.
14You are asked to standardize TypeScript settings across several teams with different codebases. How do you approach it?
Listen for: Strong answers start by inventorying current tsconfig settings, build tools, risk areas, and release cadence. They propose a shared base config with opt-in stricter layers, migration guidance, CI checks, and exception handling. They balance safety with delivery and explain why settings like noUncheckedIndexedAccess may need staged adoption.
Red flag: They mandate the strictest config everywhere immediately without a migration plan.
15A team uses heavy generic types that impress reviewers but slow compilation and confuse new engineers. What do you do?
Listen for: Look for balancing expressiveness with maintainability. They should profile type-check time, identify pathological types, simplify public APIs, move complexity behind wrappers, and document advanced patterns. Good answers keep valuable constraints while removing clever abstractions, and they consider onboarding, error message quality, and long-term ownership.
Red flag: They either ban generics entirely or defend complexity as proof of skill.
16How would you design error handling conventions for a TypeScript service fleet?
Listen for: A strong answer separates domain errors, validation errors, infrastructure failures, and programmer bugs. They discuss typed result objects versus exceptions, mapping to HTTP or message outcomes, preserving causes, observability fields, and avoiding leaking internals. They also include guidelines for retries, idempotency, and test expectations.
Red flag: They choose one mechanism for all errors without considering callers or operations.
17You need to migrate a Node.js TypeScript service from CommonJS to native ESM. What risks and steps matter?
Listen for: They should cover package.json type, tsconfig module and moduleResolution choices, file extensions in emitted imports, Jest or Vitest setup, ts-node or tsx usage, dual-package hazards, dependency compatibility, top-level await, and deployment runtime. Strong answers plan small releases and compatibility tests rather than a flag flip.
Red flag: They think changing module to esnext is the whole migration.
18A platform team wants a shared domain model package used by front end, back end, and data jobs. What boundaries would you set?
Listen for: Good answers distinguish stable contracts from business logic, avoid pulling server-only dependencies into browsers, and define serialization-safe types. They discuss schemas, generated artifacts, semantic versioning, ownership, deprecation, and package layering. Strong candidates resist making one package the dumping ground for every type in the company.
Red flag: They put all interfaces, validators, utilities, and database types into one shared package.
19How do you evaluate whether to adopt tRPC, OpenAPI code generation, or GraphQL for a TypeScript product?
Listen for: They should compare team ownership, client diversity, contract stability, caching, streaming needs, tooling maturity, deployment boundaries, and non-TypeScript consumers. Strong answers avoid tool fandom, consider migration from current APIs, runtime validation, observability, and how the choice affects versioning and independent releases.
Red flag: They recommend their favorite API style without asking about consumers and ownership.
20After an incident caused by a type assertion hiding malformed data, what changes would you lead?
Listen for: Listen for blameless analysis and concrete prevention: identify the trust boundary, add runtime validation, replace unsafe assertions, improve logging, add regression tests, and update review guidelines. Senior candidates also discuss rollout, monitoring, training, and when assertions remain acceptable with documented proof or localized scope.
Red flag: They only blame the engineer who wrote the assertion.
System design TypeScript questions
Designing real systems end to end.
21Design a TypeScript SDK for third-party customers consuming your REST API from Node.js and browsers.
Listen for: Strong candidates define generated or schema-driven types, runtime validation strategy, authentication hooks, pagination helpers, retries, abort signals, ESM/CJS packaging expectations, tree-shaking, and clear error types. They should consider versioning, backward compatibility, transport abstraction, typed examples, and how to test against contract fixtures.
Red flag: They design a thin fetch wrapper with handwritten response interfaces and no versioning plan.
22Design a type-safe event system for a large web app with analytics, audit, and product events.
Listen for: Listen for an event catalog modeled as discriminated unions or schema maps, payload validation, event versioning, ownership, privacy review points, and testable producers. Strong answers address compile-time ergonomics, runtime safety, batching, offline behavior if relevant, and preventing arbitrary string event names from spreading.
Red flag: They use a global emit(name: string, payload: any) API for everything.
23Design the package structure for a TypeScript monorepo containing a Next.js app, a Node.js API, shared UI, and shared contracts.
Listen for: A good answer sets clear dependency direction, separate browser-safe and server-only packages, project references, workspace scripts, lint boundaries, and CI caching. They should discuss contracts generated from schemas or OpenAPI, avoiding circular imports and barrel-file costs, and publishing or versioning internal packages when needed.
Red flag: They create one shared package imported by everything with no dependency rules.
24Design a background job platform in TypeScript that processes payments, emails, and data sync tasks.
Listen for: Strong answers include typed job definitions, payload validation, idempotency keys, retry and dead-letter policies, concurrency controls, observability, and graceful shutdown in Node.js. They should address schema evolution for queued jobs, poison messages, transactional boundaries, and how workers share types without sharing unsafe runtime assumptions.
Red flag: They focus on queue library choice but ignore idempotency and payload evolution.
25Design a plugin architecture for a TypeScript application where internal teams can add integrations safely.
Listen for: Look for typed plugin contracts, lifecycle hooks, capability-based permissions, versioned APIs, isolation boundaries, validation of plugin configuration, and test harnesses. Strong candidates discuss dependency management, async error handling, backward compatibility, documentation, and how to prevent plugins from reaching into internal modules.
Red flag: They expose the whole application object and trust plugin authors not to misuse it.
Build and harden a typed integration endpoint
Create a small TypeScript 5.x Node.js service or feature module that receives webhook-style JSON events, validates them at runtime, stores accepted events in memory, and exposes a typed query function or HTTP endpoint to retrieve them by status and date range. Include at least three event variants, one intentionally malformed fixture, and tests for validation, error handling, and filtering. You may use Fastify, Express, Hono, or no framework; use Vitest, Node’s test runner, or Jest. Keep the scope small enough to complete in 2–3 hours and include notes on trade-offs.
How to evaluate it
- Models events with clear discriminated unions or schema-derived types and avoids unsafe assertions.
- Validates untrusted input at runtime and returns useful, non-leaky errors.
- Keeps modules small with understandable boundaries between parsing, storage, and querying.
- Covers success, malformed input, and edge cases with meaningful tests.
- Explains trade-offs and limitations clearly in the README or review discussion.
Rather skip the interview loop?
Every Octogle TypeScript engineer has already passed a technical assessment, system design and a live interview with an engineer who has shipped TypeScript. Send a brief and get 3–5 scored profiles in 48 hours.