Interview questionsTypeScript
TypeScript interview questions and answers
30 TypeScript questions picked from Codejump's quizzes, from the basics a junior is expected to know to the details that trip up senior candidates. Each one comes with its answer and an explanation — try to answer before you open it.
Junior level TypeScript questions
1.What does
A & Bmean when both have a property with the same name?javascripttype A = { x: string; y: number }; type B = { y: string; z: boolean }; type AB = A & B; // AB.y = ?- A.AB.y = string & number = never — impossible type (string AND number simultaneously)
- B.AB.y = string | number — union of both
- C.AB.y = string — B wins because it's listed second
- D.AB.y = number — A wins because it's listed first
Show answer
Answer: A. AB.y = string & number = never — impossible type (string AND number simultaneously)
In an intersectionA & B, a property must satisfy BOTH constraints simultaneously.ymust be bothstringANDnumber:From the quiz Union & Intersection Types
2.What is the purpose of these compiler options?
javascript{ "compilerOptions": { "rootDir": "./src", "outDir": "./dist", "declaration": true } }- A.rootDir is where node_modules are installed; outDir is the TypeScript cache
- B.rootDir is the source root; outDir is the compiled output directory; mirror structure is preserved
- C.Both are optional with no default behavior
- D.outDir is only needed for JavaScript projects
Show answer
Answer: B. rootDir is the source root; outDir is the compiled output directory; mirror structure is preserved
rootDirdefines the common root for source files — it controls how paths are mirrored inoutDir.From the quiz tsconfig & Modules
3.What error does this generate?
javascriptfunction getLength<T>(value: T): number { return value.length; // ❌ ? }- A.No error — all types have .length
- B.No error — TypeScript infers T must have .length
- C.Error — generic functions can't access properties
- D.Error — TypeScript can't guarantee T has a .length property
Show answer
Answer: D. Error — TypeScript can't guarantee T has a .length property
Without a constraint,Tcan be any type — includingnumber,boolean, or{}which don't have.length. TypeScript raises an error:From the quiz Generic Basics
4.What is the difference between
public,private, andprotected?javascriptclass BankAccount { public owner: string; private balance: number; protected accountNumber: string; constructor(owner: string, balance: number, number: string) { this.owner = owner; this.balance = balance; this.accountNumber = number; } }- A.All three are identical in TypeScript — access modifiers are just documentation hints
- B.private — accessible outside the class; public — accessible only inside
- C.public — accessible everywhere; private — accessible only inside the class; protected — accessible inside the class and subclasses
- D.protected — prevents inheritance; private — allows inheritance
Show answer
Answer: C. public — accessible everywhere; private — accessible only inside the class; protected — accessible inside the class and subclasses
| Modifier | Inside class | Subclass | Outside class | |---|---|---|---| |public| ✅ | ✅ | ✅ | |protected| ✅ | ✅ | ❌ | |private| ✅ | ❌ | ❌ |From the quiz Classes & Interfaces
5.What does the
|operator create in TypeScript?javascriptfunction formatId(id: string | number): string { return `ID: ${id}`; }- A.A bitwise OR operation on two types
- B.An intersection type — the parameter must be both string AND number
- C.A union type — the parameter can be either string OR number
- D.A nullable type — equivalent to string | null
Show answer
Answer: C. A union type — the parameter can be either string OR number
The|operator creates a union type — a value that can be one of several types: The functionformatIdaccepts both strings and numbers, and TypeScript checks that only valid types are passed.From the quiz Type System Basics
6.Given this interface, which object assignment will TypeScript reject?
javascriptinterface User { name: string; age: number; }- A.const u: User = { name: "Alice", age: 30 }
- B.const u: User = { name: "Bob", age: 25, city: "Paris" }
- C.const u: User = { name: "Charlie" }
- D.const u: User = { name: "Diana", age: 0 }
Show answer
Answer: C. const u: User = { name: "Charlie" }
An interface defines the required shape of an object. Every required property must be present. Option B is valid in a variable assignment context — TypeScript performs structural typing and accepts extra properties when assigning via a variable (though object literals passed directly to functions trigger excess property checks).From the quiz TypeScript Fundamentals
7.What is a discriminant property?
javascripttype Circle = { kind: 'circle'; radius: number }; type Rectangle = { kind: 'rectangle'; width: number; height: number }; type Triangle = { kind: 'triangle'; base: number; height: number }; type Shape = Circle | Rectangle | Triangle; function area(shape: Shape): number { switch (shape.kind) { case 'circle': return Math.PI * shape.radius ** 2; case 'rectangle': return shape.width * shape.height; case 'triangle': return 0.5 * shape.base * shape.height; } }- A.kind is the discriminant — a literal-typed property shared by all union members that TypeScript uses to narrow to the correct member
- B.kind is any property shared by all union members
- C.TypeScript uses the property names (like radius, width) to narrow
- D.kind is a reserved keyword in TypeScript
Show answer
Answer: A. kind is the discriminant — a literal-typed property shared by all union members that TypeScript uses to narrow to the correct member
The discriminant is a property with a literal type ('circle','rectangle','triangle') that:- Is present in ALL union members
- Has a different literal value in each member TypeScript uses it to narrow the union:
From the quiz Union & Intersection Types
8.What does
noImplicitAnyprevent?javascript// With noImplicitAny: true function process(data) { // (A) ? return data.length; } const items = []; // (B) ? function identity<T>(x: T) { // (C) ? return x; }- A.All three cause errors — all types must be explicit
- B.None cause errors — TypeScript infers types automatically
- C.Only (A) causes an error
- D.(A) and (B) cause errors — parameters and variables without type inference; (C) is fine because T is inferred
Show answer
Answer: D. (A) and (B) cause errors — parameters and variables without type inference; (C) is fine because T is inferred
noImplicitAnyerrors when TypeScript can't infer a type and would default toany:From the quiz tsconfig & Modules
9.What is
Twhen callingcontainer()with no type argument?javascriptfunction container<T = string>(value?: T): T | undefined { return value; } const a = container(); // T = ? const b = container("hello"); // T = ? const c = container(42); // T = ?- A.a: string | undefined, b: string | undefined, c: number | undefined
- B.a: unknown, b: string, c: number
- C.a: string, b: string, c: string — default forces all to string
- D.All are any
Show answer
Answer: A. a: string | undefined, b: string | undefined, c: number | undefined
Default type parameters apply when the type can't be inferred:container()→ no argument, no inference →Tdefaults tostring→ returnsstring | undefinedcontainer("hello")→Tinferred asstring→ returnsstring | undefinedcontainer(42)→Tinferred asnumber→ returnsnumber | undefined
From the quiz Generic Basics
10.What does this TypeScript shorthand do?
javascriptclass Point { constructor( public x: number, public y: number ) {} }- A.x and y are only available inside the constructor
- B.This syntax is only valid for readonly properties
- C.public in constructor parameters creates global variables
- D.It's shorthand for declaring x and y as class properties AND assigning them in the constructor — equivalent to 6 lines of manual code
Show answer
Answer: D. It's shorthand for declaring x and y as class properties AND assigning them in the constructor — equivalent to 6 lines of manual code
Constructor parameter shorthand (parameter properties) auto-declares class properties and assigns them:From the quiz Classes & Interfaces
Mid level TypeScript questions
11.What do
-?and+?do in mapped types?javascripttype Required<T> = { [K in keyof T]-?: T[K] }; type Optional<T> = { [K in keyof T]+?: T[K] }; interface Config { host?: string; port?: number; debug?: boolean; } type StrictConfig = Required<Config>; type FlexConfig = Optional<Config>; // same as Config in this case- A.-? removes undefined from value types; +? adds it
- B.-? removes the optional modifier; +? adds the optional modifier
- C.+ and - are operators on boolean types only
- D.These modifiers only work on readonly, not ?
Show answer
Answer: B. -? removes the optional modifier; +? adds the optional modifier
Mapped type modifiers control the?(optional) andreadonlyflags: The built-inRequired<T>uses exactly-?:From the quiz Template Literals & Inference
12.Why might a project require
isolatedModules: true?javascript// tsconfig: "isolatedModules": true // File 1 — const enum: export const enum Direction { Up, Down, Left, Right } // File 2 — using it: import { Direction } from './file1'; const d = Direction.Up; // ?- A.Error — const enum is forbidden with isolatedModules because transpilers (Babel, esbuild) process one file at a time and can't inline const enum values
- B.isolatedModules has no effect on const enum
- C.const enum is automatically converted to a regular enum
- D.Works fine — isolatedModules only affects type-only imports
Show answer
Answer: A. Error — const enum is forbidden with isolatedModules because transpilers (Babel, esbuild) process one file at a time and can't inline const enum values
isolatedModules: truemirrors how Babel and esbuild work — they transpile each file independently without cross-file type information: UseisolatedModuleswhen your build tool is Babel, esbuild, or SWC — it catches patterns that break single-file transpilation.From the quiz Decorators & Project Setup
13.What does
ReturnTypeextract?javascriptasync function fetchUser(id: string): Promise<{ id: string; name: string }> { // ... return { id, name: "Alice" }; } type FetchUserResult = ReturnType<typeof fetchUser>; // FetchUserResult = ?- A.{ id: string; name: string }
- B.string
- C.Promise<{ id: string; name: string }>
- D.(id: string) => Promise<{ id: string; name: string }>
Show answer
Answer: C. Promise<{ id: string; name: string }>
ReturnType<T>extracts the return type of a function type — for async functions, that's the fullPromise<...>type: To get the unwrapped type, useAwaited:From the quiz Utility Types
14.What is the difference between instance and static members?
javascriptclass Counter { static count: number = 0; id: number; constructor() { Counter.count++; this.id = Counter.count; } static reset() { Counter.count = 0; } }- A.static count belongs to each instance; id is shared across all instances
- B.Counter.count and new Counter().count access the same memory
- C.static members can only be numbers
- D.static count belongs to the class itself (shared across all instances); id belongs to each instance
Show answer
Answer: D. static count belongs to the class itself (shared across all instances); id belongs to each instance
Static members live on the class constructor itself, not on individual instances:From the quiz Inheritance & Polymorphism
15.How does the
inoperator help TypeScript narrow types?javascripttype Cat = { meow: () => void }; type Dog = { bark: () => void }; function makeSound(animal: Cat | Dog) { if ('meow' in animal) { animal.meow(); // ? } }- A.in checks if the property exists at runtime but TypeScript still sees Cat | Dog
- B.TypeScript narrows animal to Cat inside the if block because only Cat has meow
- C.in only works with classes, not type aliases
- D.TypeScript narrows animal to never inside the if
Show answer
Answer: B. TypeScript narrows animal to Cat inside the if block because only Cat has meow
Theinoperator narrows to the union members that include the checked property: This is the idiomatic way to narrow discriminated object unions where the discriminant is a property name.From the quiz Mapped & Conditional Types
16.What does
Partial<User>produce?javascriptinterface User { name: string; email: string; age: number; } function updateUser(id: string, patch: Partial<User>): void { /* ... */ }- A.A type where all properties are required (same as User)
- B.A type containing only the first property of User
- C.A type where all properties of User become optional
- D.A type where all properties become null
Show answer
Answer: C. A type where all properties of User become optional
Partial<T>is a built-in TypeScript utility type that makes all properties ofToptional: This is extremely useful forPATCH-style update functions.From the quiz TypeScript Intermediate
17.What is the resolved type here?
javascriptasync function fetchData(): Promise<{ users: { id: string; name: string }[] }> { return { users: [] }; } type ResponseData = Awaited<ReturnType<typeof fetchData>>; type UserList = ResponseData['users']; type User = UserList[number];- A.User = string
- B.User = { users: { id: string; name: string }[] }
- C.User = { id: string; name: string }
- D.User = unknown
Show answer
Answer: C. User = { id: string; name: string }
Step by step: 1.ReturnType<typeof fetchData>=Promise<{ users: { id: string; name: string }[] }>2.Awaited<...>={ users: { id: string; name: string }[] }3.ResponseData['users']={ id: string; name: string }[]4.UserList[number]={ id: string; name: string }— accessing array element typeFrom the quiz Template Literals & Inference
18.What does
skipLibCheck: truedo?javascript{ "compilerOptions": { "skipLibCheck": true } }- A.Skips type-checking of all .ts files in your project
- B.Skips importing external libraries
- C.Skips type-checking of declaration files (.d.ts) — including those in node_modules
- D.Disables strict mode for third-party code
Show answer
Answer: C. Skips type-checking of declaration files (.d.ts) — including those in node_modules
skipLibCheck: trueskips type-checking of ALL.d.tsfiles:From the quiz Decorators & Project Setup
19.What does
Parametersextract?javascriptfunction createUser(name: string, age: number, role: 'admin' | 'user'): void { /* ... */ } type CreateArgs = Parameters<typeof createUser>;- A.[string, number, 'admin' | 'user'] — a tuple of parameter types
- B.string | number | 'admin' | 'user' — a union of parameter types
- C.{ name: string; age: number; role: 'admin' | 'user' } — an object
- D.void
Show answer
Answer: A. [string, number, 'admin' | 'user'] — a tuple of parameter types
Parameters<T>extracts the parameter types as a tuple:From the quiz Utility Types
20.What does
superdo in a subclass constructor?javascriptclass Animal { constructor(public name: string) {} speak() { return `${this.name} makes a sound.`; } } class Dog extends Animal { constructor(name: string, public breed: string) { super(name); // ? } }- A.super(name) calls Animal.speak() method
- B.super is only valid in method overrides, not constructors
- C.super(name) calls the parent class constructor — required before using this in a subclass constructor
- D.super(name) copies all parent properties to the child
Show answer
Answer: C. super(name) calls the parent class constructor — required before using this in a subclass constructor
In a derived class constructor,super(...)must be called before any use ofthis. It invokes the parent class constructor:From the quiz Inheritance & Polymorphism
Senior level TypeScript questions
21.What type is produced?
javascripttype JSONValue = | string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue }; type IsJSON<T> = T extends JSONValue ? true : false; type A = IsJSON<string>; type B = IsJSON<{ x: number; y: number }>; type C = IsJSON<Date>; type D = IsJSON<undefined>;- A.A = true, B = true, C = true, D = true
- B.A = true, B = true, C = false, D = false
- C.A = true, B = false, C = false, D = false
- D.A = true, B = true, C = false, D = true
Show answer
Answer: B. A = true, B = true, C = false, D = false
JSONValueincludesstring, numbers, booleans, null, arrays, and plain objects:From the quiz Conditional Types & Infer
22.What does this declaration file accomplish?
javascript// src/global.d.ts declare module '*.svg' { const content: string; export default content; } declare module '*.md' { const content: string; export default content; }- A.Creates runtime handlers for .svg and .md imports
- B.These declarations are redundant — TypeScript handles all file types natively
- C.Converts SVG files to strings automatically during compilation
- D.Tells TypeScript the type of these file imports — prevents "cannot find module" errors when importing non-JS files
Show answer
Answer: D. Tells TypeScript the type of these file imports — prevents "cannot find module" errors when importing non-JS files
TypeScript only understands JavaScript/TypeScript modules natively. For other file types: The actual transformation is done by the bundler (Vite, webpack) — the ambient module declaration just tells TypeScript the types.From the quiz Compiler API & References
23.What is the return type of
compose?javascriptfunction compose<A, B, C>( f: (b: B) => C, g: (a: A) => B ): (a: A) => C { return (a: A) => f(g(a)); } const addOne = (n: number): number => n + 1; const toString = (n: number): string => String(n); const addOneThenString = compose(toString, addOne); const result = addOneThenString(5); // ?- A."5" — only the second function applies
- B.6 — typed as number
- C."6" — 5 + 1 = 6, then String(6) = "6"; typed as string
- D.Compile error — compose doesn't infer types
Show answer
Answer: C. "6" — 5 + 1 = 6, then String(6) = "6"; typed as string
TypeScript infers the type parameters:g = addOne:(number) => number→A = number,B = numberf = toString:(number) => string→B = number,C = stringcompose(toString, addOne)→(number) => string
From the quiz Advanced Generics
24.What does a method decorator receive?
javascriptfunction Log(target: any, key: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`Calling ${key} with`, args); return original.apply(this, args); }; return descriptor; } class Service { @Log process(data: string): string { return data.toUpperCase(); } }- A.target = the instance, key = the method name, descriptor = the method function
- B.target = the class prototype (for instance methods), key = the method name, descriptor = the property descriptor (wrapping the function)
- C.target = the class constructor, key = the class name, descriptor = all methods
- D.Method decorators only receive target — the other parameters are optional
Show answer
Answer: B. target = the class prototype (for instance methods), key = the method name, descriptor = the property descriptor (wrapping the function)
Method decorator parameters:target— the prototype of the class (for instance methods) or the constructor (for static methods)key— the name of the decorated methoddescriptor— thePropertyDescriptorcontaining.value(the function),.writable,.enumerable
From the quiz Advanced OOP Patterns
25.What is the difference between
ExtractandExclude?javascripttype A = Extract<string | number | boolean, string | number>; type B = Exclude<string | number | boolean, string | number>;- A.A = string | number, B = boolean
- B.A = boolean, B = string | number
- C.Both are string | number | boolean
- D.A = never, B = boolean
Show answer
Answer: A. A = string | number, B = boolean
Extract<T, U>keeps only the members ofTthat are assignable toUExclude<T, U>removes the members ofTthat are assignable toU
From the quiz Advanced Type Engineering
26.What is the correct way to handle each shape's area calculation using a discriminated union?
javascripttype Shape = | { kind: "circle"; radius: number } | { kind: "square"; side: number } | { kind: "rectangle"; width: number; height: number };- A.Use shape.kind with switch or if to narrow the union to a specific member
- B.Use typeof shape to narrow between shapes
- C.Use instanceof to narrow between shapes
- D.Cast shape as any and access properties freely
Show answer
Answer: A. Use shape.kind with switch or if to narrow the union to a specific member
A discriminated union has a common literal property (the discriminant) — herekind. TypeScript narrows the type when you check that property: TypeScript provides exhaustiveness checking: if you miss a case, the function may not return in all branches, which TypeScript can catch.From the quiz TypeScript Advanced
27.What does this complex mapped type produce?
javascripttype Serialize<T> = { [K in keyof T]: T[K] extends Date ? string : T[K] extends (infer U)[] ? Serialize<U>[] : T[K] extends object ? Serialize<T[K]> : T[K]; }; interface Data { name: string; createdAt: Date; tags: string[]; address: { city: string; updatedAt: Date }; } type SerializedData = Serialize<Data>;- A.string
- B.{ name: string; createdAt: Date; tags: string[]; address: { city: string; updatedAt: Date } }
- C.{ name: string; createdAt: string; tags: string[]; address: { city: string; updatedAt: string } }
- D.Data unchanged
Show answer
Answer: C. { name: string; createdAt: string; tags: string[]; address: { city: string; updatedAt: string } }
Serialize<T>recursively transformsDate→string:From the quiz Conditional Types & Infer
28.When should you use triple-slash references?
javascript/// <reference types="node" /> /// <reference path="../global.d.ts" /> /// <reference lib="dom" /> // Top of a .ts file- A.Triple-slash directives are legacy — prefer import type for code; they're still useful for global .d.ts files and forcing type inclusion
- B.Triple-slash directives are the modern way to import types in TypeScript
- C.They only work in .d.ts files, not regular .ts files
- D./// <reference types="node" /> replaces @types/node in package.json
Show answer
Answer: A. Triple-slash directives are legacy — prefer import type for code; they're still useful for global .d.ts files and forcing type inclusion
Triple-slash directives are compiler directives (not imports):From the quiz Compiler API & References
29.What does
Awaited<T>unwrap?javascripttype T1 = Awaited<Promise<string>>; type T2 = Awaited<Promise<Promise<number>>>; type T3 = Awaited<string>;- A.T1 = string, T2 = Promise<number>, T3 = string
- B.T1 = string, T2 = number, T3 = never
- C.T1 = Promise<string>, T2 = Promise<Promise<number>>, T3 = string
- D.T1 = string, T2 = number, T3 = string
Show answer
Answer: D. T1 = string, T2 = number, T3 = string
Awaited<T>recursively unwrapsPromisetypes: This replaces older patterns likeReturnType<typeof fn>for async functions where you'd needAwaited<ReturnType<...>>.From the quiz Advanced Generics
30.What is the difference between
#fieldandprivate field?javascriptclass A { private tsPrivate = 1; #jsPrivate = 2; } const a = new A(); (a as any).tsPrivate; // ? (a as any).jsPrivate; // ?- A.Both are inaccessible — they compile to the same JavaScript
- B.tsPrivate is accessible via as any at runtime (TypeScript-only check); #jsPrivate is truly inaccessible at runtime (JavaScript native enforcement)
- C.#jsPrivate is only accessible from subclasses
- D.private fields can be accessed via reflection; # fields cannot be reflected on
Show answer
Answer: B. tsPrivate is accessible via as any at runtime (TypeScript-only check); #jsPrivate is truly inaccessible at runtime (JavaScript native enforcement)
TypeScriptprivateis compile-time only — it compiles to a regular JavaScript property, accessible at runtime: JavaScript#privateFieldis runtime-enforced — it's a WeakMap-based private field in JavaScript itself: Even with reflection orObject.keys(),#fields are hidden.From the quiz Advanced OOP Patterns
Practise 650+ more TypeScript questions
Timed quizzes with instant feedback, the questions you miss coming back until they stick, coding challenges and AI mock interviews — free to start.