DevAcademy
All interview questions
90+ Questions

TypeScript Interview Questions & Answers

Curated TypeScript interview questions with detailed answers, grouped by topic. Search, revise and get interview-ready.

Filter by difficulty:

TypeScript Introduction

Q1. What is TypeScript, in relation to JavaScript?

TypeScript is a typed superset of JavaScript — every valid JavaScript program is also valid TypeScript. It adds optional static types, which are checked at compile time and then compiled away into plain JavaScript.

Q2. Do browsers run TypeScript directly?

No. TypeScript must be compiled to JavaScript first (by tsc or a bundler’s TypeScript integration) before it can run in a browser or Node.js.

Q3. What happens to TypeScript types at runtime?

IntermediateLearn topic →

They are completely erased during compilation. The compiled JavaScript output contains no type information at all, so TypeScript adds zero runtime performance overhead.

TypeScript Setup

Q4. What command compiles a .ts file into JavaScript?

tsc (the TypeScript compiler), e.g. npx tsc file.ts, or simply npx tsc to compile an entire project based on its tsconfig.json.

Q5. What is the purpose of tsconfig.json?

It configures how the compiler behaves for a project — which files to include, which JavaScript version to target, and which strictness rules to enforce.

Q6. How does an editor show type errors before you even run the compiler?

IntermediateLearn topic →

Editors like VS Code run the TypeScript language service in the background, which continuously type-checks your code and reports errors live as you type.

Basic Types

Q7. Does TypeScript have separate types for integers and floating-point numbers?

No — TypeScript has a single number type that covers all numeric values, whether whole numbers or decimals.

Q8. What does strictNullChecks do?

IntermediateLearn topic →

It makes null and undefined distinct types that are not automatically assignable to other types unless explicitly included, e.g. string | null — preventing a large class of "cannot read property of undefined" runtime errors.

Q9. How do you type an array of numbers?

Either number[] or the equivalent generic form Array<number>.

Arrays & Tuples

Q10. What is the key difference between an array type and a tuple type?

An array type describes a list of elements all sharing the same type, of any length. A tuple has a fixed length, with each position given its own specific type.

Q11. How do you write a tuple type for a coordinate pair?

[number, number] — the first and second elements are each typed individually, and the tuple must have exactly two elements.

Q12. What does a rest element in a tuple type allow?

IntermediateLearn topic →

It allows a variable number of trailing elements of a given type after the fixed positions, e.g. [name: string, ...scores: number[]].

Enums

Q13. What value do numeric enum members receive by default?

They auto-increment starting from 0, unless a custom starting value is given, in which case subsequent members increment from there.

Q14. Do string enum members get automatic default values?

IntermediateLearn topic →

No — every member of a string enum must be given an explicit value.

Q15. What is a common alternative to enum, and why might a team prefer it?

A union of string literal types, e.g. type Status = "PENDING" | "ACTIVE". It requires no extra runtime code (unlike a regular enum, which compiles into a real object) and integrates more naturally with plain JSON.

any, unknown, never & void

Q16. What is the key difference between any and unknown?

IntermediateLearn topic →

Both accept any value, but unknown requires you to narrow it to a specific type before you can use it, while any bypasses type checking entirely with no such requirement.

Q17. What does the never type represent?

IntermediateLearn topic →

A value that can never occur — used for functions that always throw or never return, and for exhaustiveness checks over union types in a switch statement.

Q18. When would a function’s return type be void?

When the function doesn’t return a meaningful value and exists purely for its side effects, like logging a message.

Type Inference

Q19. Do you need to annotate every variable explicitly in TypeScript?

No — TypeScript infers types automatically from initial values, return statements, and surrounding context (contextual typing) in most cases.

Q20. What type would TypeScript infer for the array [1, "two", 3]?

IntermediateLearn topic →

(string | number)[] — TypeScript infers a union covering every element type present in the array.

Q21. What does noImplicitAny protect against?

It turns what would otherwise be a silent, implicit any type (for example, an uninitialized variable with no type context) into a compile error instead, preserving type safety.

Type Aliases

Q22. What does the type keyword do?

It creates a reusable, named alias for any type — a primitive, object shape, union, function type, or anything else.

Q23. Does a type alias create a genuinely new, distinct type?

IntermediateLearn topic →

No — it’s just another name for an existing type. Two aliases pointing at the same underlying shape are fully interchangeable.

Q24. Can a type alias describe a function’s signature?

IntermediateLearn topic →

Yes, e.g. type MathOperation = (a: number, b: number) => number, useful for typing callbacks consistently.

Interfaces

Q25. What is structural typing, and how does it relate to interfaces?

IntermediateLearn topic →

Structural typing means an object satisfies an interface if it has the required shape, regardless of how it was created or declared — TypeScript checks shape compatibility, not explicit type names.

Q26. How does one interface extend another?

With the extends keyword, e.g. interface Dog extends Animal { ... }, inheriting all members of the parent interface.

Q27. How does a class formally satisfy an interface?

IntermediateLearn topic →

With the implements keyword, e.g. class Circle implements Shape, which guarantees the class provides every member the interface requires.

Function Types

Q28. What happens to a parameter when it’s given a default value?

It automatically becomes optional — callers may omit it, in which case the default value is used.

Q29. What does a rest parameter like ...numbers: number[] collect?

Any number of remaining arguments passed to the function, gathered into a typed array.

Q30. What are function overloads used for?

They let a single function accept different combinations of parameter types, each with its own precise return type, by declaring multiple call signatures above one shared implementation.

Union & Intersection Types

Q31. What does a union type like string | number mean?

The value can be either a string or a number — but you can only use operations valid for both until the value is narrowed to one specific type.

Q32. What does an intersection type like A & B require?

IntermediateLearn topic →

The value must satisfy both A and B simultaneously — it has all the members of every combined type.

Q33. What is a discriminated union?

A union of object types that share a common literal "tag" property (like kind: "circle"), which TypeScript can check in a conditional to automatically and safely narrow to the exact matching shape.

Literal Types

Q34. What does the literal type "success" allow as a valid value?

Only the exact string "success" — not any arbitrary string.

Q35. Why is a const variable typically inferred more narrowly than a let variable with the same value?

IntermediateLearn topic →

Since a const can never be reassigned, TypeScript infers its most specific literal type. A let variable is inferred more broadly (e.g. string) since it might be reassigned to a different value of the same general type later.

Q36. What does the as const assertion do?

It locks an object or array to its most specific literal types and makes it deeply readonly, commonly used for defining fixed configuration values.

Object Types

Q37. What is an index signature used for?

IntermediateLearn topic →

Typing an object whose exact keys aren’t known ahead of time, but whose values all share a common type, like a dictionary — e.g. { [key: string]: number }.

Q38. What does Record<string, number> describe?

IntermediateLearn topic →

An object type with string keys and number values — a more concise, commonly preferred alternative to writing an index signature by hand.

Q39. When does TypeScript perform excess property checks?

When an object literal is passed directly to a typed parameter or variable — it flags properties on the literal that don’t exist on the target type, catching likely typos.

Optional & Readonly Properties

Q40. What type does an optional property (name?: string) implicitly include?

undefined — its type becomes string | undefined.

Q41. What happens if you try to reassign a readonly property after an object is created?

TypeScript reports a compile-time error — readonly properties can be set once, typically during initialization, but never reassigned afterward.

Q42. Does readonly provide true runtime immutability, like Object.freeze()?

No — like all TypeScript type features, readonly is a compile-time-only check. It’s erased during compilation and provides no runtime enforcement on its own.

Type Assertions

Q43. Does a type assertion (as) convert a value at runtime?

IntermediateLearn topic →

No — it only changes how the compiler treats the value’s type. No actual conversion or validation happens.

Q44. What does the non-null assertion operator (!) do?

IntermediateLearn topic →

It tells the compiler a value is definitely not null or undefined, even though its declared type says it might be — a narrower, more targeted form of assertion.

Q45. What happens if a type assertion turns out to be incorrect?

TypeScript won’t catch the mistake, since the safety check was intentionally skipped — it surfaces as a runtime error instead, exactly the kind of bug TypeScript is normally meant to prevent.

Classes

Q46. What does the constructor parameter property shorthand do?

IntermediateLearn topic →

Writing constructor(public name: string) both declares the class property and assigns it from the constructor argument in one step, removing repetitive boilerplate.

Q47. What must a subclass constructor call before using this, if the parent has its own constructor?

super() — it must be called first, before this can be accessed, to properly initialize the parent class.

Q48. Can an abstract class be instantiated directly?

IntermediateLearn topic →

No — an abstract class exists only to be extended. It can declare abstract methods that concrete subclasses are required to implement.

Access Modifiers

Q49. What is the default access modifier if none is specified?

public — accessible from anywhere, including outside the class.

Q50. What is the difference between private and protected?

IntermediateLearn topic →

private members are accessible only within the declaring class itself. protected members are also accessible from subclasses, but not from outside code.

Q51. What is the key difference between TypeScript’s private and native # private fields?

TypeScript’s private is a compile-time-only check that’s erased during compilation, with no runtime enforcement. Native # fields are truly private and enforced by the JavaScript runtime itself.

Interfaces vs Type Aliases

Q52. What is declaration merging, and which one supports it?

Declaration merging automatically combines multiple declarations with the same name into one. Only interface supports this — declaring the same type alias twice is a compile error.

Q53. What can type describe that interface cannot?

IntermediateLearn topic →

Unions, intersections, tuples, and primitive aliases directly — an interface can only describe object/class shapes.

Q54. Can a class implement a type alias the same way it implements an interface?

IntermediateLearn topic →

Yes, as long as the type alias describes an object shape — both interface and a compatible type alias can be used with implements.

Generics

Q55. What problem do generics solve?

IntermediateLearn topic →

They let a function, interface, or class stay reusable across many types while remaining fully type-safe, avoiding the alternative of using any (losing safety) or duplicating code per type.

Q56. In function identity<T>(value: T): T, how is T determined at a call site?

IntermediateLearn topic →

TypeScript infers it automatically from the argument passed in — it doesn’t need to be specified manually in most cases.

Q57. Can interfaces and classes be generic, not just functions?

IntermediateLearn topic →

Yes — both interfaces (e.g. interface ApiResponse<T>) and classes (e.g. class Box<T>) can accept type parameters, just like functions.

Generic Constraints

Q58. Why can’t you access value.length on an unconstrained generic <T>?

IntermediateLearn topic →

Because T could be any type, and TypeScript can’t guarantee every possible type has a length property — accessing it would be unsafe.

Q59. What does <T extends HasLength> do?

IntermediateLearn topic →

It restricts T to only types that satisfy the HasLength shape, which then safely unlocks access to the properties that shape guarantees.

Q60. What does the pattern <T, K extends keyof T> typically guarantee?

That K is restricted to one of the actual property keys of T, enabling safe, precisely-typed property access like obj[key] without risking an invalid key.

Type Narrowing

Q61. What does "narrowing" mean in TypeScript?

IntermediateLearn topic →

Deducing a more specific type for a value within a certain block of code, based on a runtime check you’ve already performed, like typeof or instanceof.

Q62. What does the in operator narrow based on?

IntermediateLearn topic →

Whether an object has a particular property — useful for narrowing unions of plain object shapes that don’t share a class hierarchy.

Q63. Why are discriminated unions considered the most robust narrowing pattern?

Because every member shares a common literal "tag" property, checking that single property narrows the entire object safely and exhaustively, with strong editor support and compile-time exhaustiveness checks.

Utility Types

Q64. What does Partial<T> do?

It creates a new type where every property of T becomes optional — commonly used for typing partial update payloads.

Q65. What is the difference between Pick<T, K> and Omit<T, K>?

IntermediateLearn topic →

Pick keeps only the listed keys K from T, while Omit keeps everything except the listed keys K.

Q66. What does ReturnType<typeof someFunction> give you?

IntermediateLearn topic →

The type of the value that function returns, extracted automatically without needing to write it out manually.

Mapped Types

Q67. What does a mapped type do, conceptually?

IntermediateLearn topic →

It builds a new type by iterating over the keys of an existing type (or a union of literals) and applying the same transformation to each one — essentially a "map()" for types.

Q68. How are the built-in Partial<T> and Readonly<T> implemented?

They are themselves just mapped types under the hood, e.g. { [K in keyof T]?: T[K] } for Partial.

Q69. What does the as clause inside a mapped type allow?

Renaming each key as the type maps over it — for example, prefixing every key with "get" to build a set of getter method names.

Conditional Types

Q70. What does T extends U ? X : Y mean in a conditional type?

If T is assignable to U, the type resolves to X; otherwise it resolves to Y — the type-level equivalent of a ternary expression.

Q71. What does the infer keyword do?

It introduces a new type variable inside an extends clause, letting TypeScript extract and capture part of a matched type, like a function’s return type or an array’s element type.

Q72. What happens when a conditional type is applied to a union type?

It automatically distributes over each member of the union individually, then combines the results back into a union — this is called a distributive conditional type.

Custom Type Guards

Q73. What does a function return type like value is User indicate?

IntermediateLearn topic →

It’s a type predicate — if the function returns true, TypeScript narrows the checked value to the User type for the rest of that code path.

Q74. Why are custom type guards especially useful for data typed as unknown?

They let you safely validate and narrow unknown values — like a parsed API response — before trusting their shape, centralizing that validation logic in one reusable place.

Q75. Does TypeScript verify that a type guard’s implementation is logically correct?

No — it trusts the declared "is Type" return type. An incorrectly implemented guard will still compile fine, but can silently narrow to the wrong type.

Modules

Q76. Does TypeScript use a different import/export syntax from JavaScript?

No — it uses the same ES module syntax, with the addition of an optional type-only import form (import type).

Q77. What does import type guarantee?

IntermediateLearn topic →

That the import is completely erased from the compiled JavaScript output, since it’s only ever used for type checking, never at runtime.

Q78. Should new TypeScript projects use namespaces or ES modules?

IntermediateLearn topic →

ES modules — namespaces are a legacy feature that predates ES modules and don’t integrate well with modern bundlers and tree-shaking.

Declaration Files

Q79. What does a .d.ts file contain?

IntermediateLearn topic →

Only type information — no runtime implementation code. It describes the shape of existing JavaScript so TypeScript can type-check code that uses it.

Q80. What is the @types npm scope used for?

IntermediateLearn topic →

It hosts community-maintained type definitions (from the DefinitelyTyped project) for popular JavaScript packages that don’t ship their own built-in types.

Q81. What does declare const APP_VERSION: string tell the compiler?

That a value named APP_VERSION exists at runtime (perhaps injected by a build tool), without TypeScript needing to see where it was actually defined.

Decorators

Q82. What does a decorator let you do?

IntermediateLearn topic →

Observe, modify, or replace a class, method, property, or accessor at the point it’s defined, using concise @ syntax — commonly used for logging, validation, and dependency injection.

Q83. What is a decorator factory?

A function that returns a decorator, allowing configuration options to be passed in, e.g. @MinLength(8) instead of a fixed, unconfigurable decorator.

Q84. Which frameworks make heavy use of decorators?

IntermediateLearn topic →

Angular (@Component, @Injectable) and NestJS (@Controller, @Get), among others — most developers encounter decorators as consumers of these frameworks even if they rarely write custom ones.

tsconfig Deep Dive

Q85. What is the difference between the target and lib compiler options?

target controls what JavaScript syntax the compiled output uses. lib controls which built-in type definitions (like DOM or ES2020 APIs) are available to your code — they are independent settings.

Q86. What individual flags does strict enable?

Several flags at once, including noImplicitAny, strictNullChecks, strictFunctionTypes, and strictPropertyInitialization — each catching a different category of type mistake.

Q87. What does noUncheckedIndexedAccess change?

It makes indexing into an object or array with an index signature return T | undefined instead of just T, correctly reflecting that the key might not actually exist — it is not included in strict by default.

TypeScript Best Practices

Q88. Why is it easier to start a project with strict mode than to enable it later?

IntermediateLearn topic →

Enabling strict mode on a large, loosely-typed codebase later surfaces a large batch of newly-flagged errors all at once, whereas starting strict spreads that cost out naturally as each file is written.

Q89. Why should data from an external API be validated with a type guard, not just typed?

TypeScript types are erased at runtime and don’t verify that real data actually matches — response.json() is typed as any by default, so trusting an assumed shape without validation can silently let mismatched data flow through your program.

Q90. What is the benefit of modeling application state as a discriminated union instead of many optional fields?

It makes invalid or contradictory states (like "loading" and "data present" at the same time) genuinely unrepresentable in the type system, rather than merely discouraged by convention.