Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials
TypeScript

Top 50 TypeScript Interview Questions

Curated questions covering types, interfaces, generics, decorators, enums, utility types, mapped types, and TypeScript configuration.

01

What is TypeScript and why use it over JavaScript?

TypeScript is a statically typed superset of JavaScript that compiles to plain JavaScript. Benefits: catch errors at compile time, better IDE support (autocomplete, refactoring), self-documenting code, safer large-scale applications, and first-class support for modern JavaScript features.

02

What is the difference between type and interface?

  • interface - can be extended with extends and merged (declaration merging). Best for object shapes and public APIs.
  • type - more flexible; supports unions, intersections, primitives, tuples, and mapped types. Cannot be merged.
  • Prefer interface for object shapes; use type for unions, intersections, and complex types.
Example
interface User { name: string; age: number; }\ninterface User { email: string; } // merged - OK\n\ntype ID = string | number; // union - only with type\ntype Point = { x: number } & { y: number }; // intersection
03

What are generics in TypeScript?

Generics allow writing reusable, type-safe code that works with multiple types. They act as type placeholders resolved at usage time.

Example
function identity<T>(value: T): T { return value; }\nidentity<string>("hello"); // T = string\nidentity<number>(42);      // T = number\n\ninterface ApiResponse<T> {\n  data: T;\n  status: number;\n  message: string;\n}
04

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

  • any - disables type checking. Avoid it as it defeats the purpose of TypeScript.
  • unknown - type-safe alternative to any. Must narrow the type before using it.
  • never - represents values that never occur. Used for exhaustive checks and functions that always throw.
Example
let a: unknown = "hello";\nif (typeof a === "string") a.toUpperCase(); // must narrow first\n\nfunction fail(msg: string): never {\n  throw new Error(msg); // never returns\n}
05

What are TypeScript utility types?

Utility types are built-in generic types that transform existing types.

  • Partial - makes all properties optional.
  • Required - makes all properties required.
  • Readonly - makes all properties read-only.
  • Pick - picks a subset of properties.
  • Omit - removes specified properties.
  • Record - creates an object type with keys K and values V.
  • ReturnType - extracts the return type of a function.
  • NonNullable - removes null and undefined.
Example
interface User { id: number; name: string; email: string; }\ntype PartialUser = Partial<User>;\ntype UserPreview = Pick<User, "id" | "name">;\ntype UserWithoutEmail = Omit<User, "email">;\ntype StringMap = Record<string, string>;
06

What is type narrowing?

Type narrowing refines a broad type to a more specific one within a conditional block using control flow analysis.

Example
function process(value: string | number) {\n  if (typeof value === "string") {\n    return value.toUpperCase(); // narrowed to string\n  }\n  return value.toFixed(2); // narrowed to number\n}\n\nfunction handle(err: unknown) {\n  if (err instanceof Error) console.log(err.message);\n}
07

What are enums in TypeScript?

Enums define a set of named constants. TypeScript supports numeric enums (default), string enums, and const enums.

Example
enum Direction { Up, Down, Left, Right } // 0,1,2,3\n\nenum Status { Active = "ACTIVE", Inactive = "INACTIVE" } // string enum\n\nconst enum Color { Red, Green, Blue } // inlined at compile time
08

What is the difference between interface extending and type intersection?

  • interface extends - creates a new interface inheriting all members. Errors on conflicting property types.
  • type intersection (&) - combines types. Conflicting property types result in never.
Example
interface A { x: number; }\ninterface B extends A { y: number; } // B has x and y\n\ntype C = { x: number } & { y: number }; // same result\ntype Conflict = { x: string } & { x: number }; // x becomes never
09

What are decorators in TypeScript?

Decorators are special declarations that attach metadata or modify classes, methods, properties, or parameters. Widely used in Angular and NestJS. Enable with experimentalDecorators in tsconfig.

Example
function Log(target: any, key: string, descriptor: PropertyDescriptor) {\n  const original = descriptor.value;\n  descriptor.value = function (...args: any[]) {\n    console.log(`Calling ${key} with`, args);\n    return original.apply(this, args);\n  };\n  return descriptor;\n}\n\nclass Service {\n  @Log\n  greet(name: string) { return `Hello, ${name}`; }\n}
10

What is a union type and an intersection type?

  • Union (|) - a value can be one of several types. Use type guards to narrow.
  • Intersection (&) - a value must satisfy all combined types simultaneously.
Example
type StringOrNumber = string | number;\ntype AdminUser = User & { adminLevel: number };\n\nfunction format(val: string | number): string {\n  return typeof val === "string" ? val : val.toString();\n}
11

What is the readonly modifier?

readonly prevents a property from being reassigned after initialization. It applies at compile time only. Use Readonly utility type to make all properties readonly.

Example
interface Config {\n  readonly apiUrl: string;\n  readonly timeout: number;\n}\nconst config: Config = { apiUrl: "/api", timeout: 3000 };\n// config.apiUrl = "/new"; // Error: cannot assign to readonly property
12

What are mapped types?

Mapped types create new types by transforming each property of an existing type. They are the foundation of utility types like Partial, Readonly, and Record.

Example
type Nullable<T> = { [K in keyof T]: T[K] | null };\ntype Optional<T> = { [K in keyof T]?: T[K] };\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] }; // remove readonly\n\ninterface User { id: number; name: string; }\ntype NullableUser = Nullable<User>; // { id: number|null; name: string|null }
13

What is a conditional type?

Conditional types select a type based on a condition: T extends U ? X : Y. They enable powerful type-level logic.

Example
type IsString<T> = T extends string ? true : false;\ntype A = IsString<string>; // true\ntype B = IsString<number>; // false\n\ntype NonNullable<T> = T extends null | undefined ? never : T;\ntype Flatten<T> = T extends Array<infer U> ? U : T;
14

What is the difference between as and satisfies?

  • as - type assertion. Overrides TypeScript inference. Can be unsafe.
  • satisfies (TS 4.9+) - validates that a value matches a type without widening it. Safer than as.
Example
const palette = {\n  red: [255, 0, 0],\n  green: "#00ff00",\n} satisfies Record<string, string | number[]>;\n\n// palette.red is still number[], not string | number[]\npalette.red.map(x => x); // OK - type preserved
15

What is a discriminated union?

A discriminated union is a union of types that share a common literal property (discriminant). TypeScript uses the discriminant to narrow the type in switch/if statements.

Example
type Shape =\n  | { kind: "circle"; radius: number }\n  | { kind: "square"; side: number };\n\nfunction area(shape: Shape): number {\n  switch (shape.kind) {\n    case "circle": return Math.PI * shape.radius ** 2;\n    case "square": return shape.side ** 2;\n  }\n}
16

What is the keyof operator?

keyof produces a union of all property keys of a type. Combined with generics, it enables type-safe property access.

Example
interface User { id: number; name: string; email: string; }\ntype UserKeys = keyof User; // "id" | "name" | "email"\n\nfunction getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {\n  return obj[key]; // fully type-safe\n}
17

What is the typeof operator in TypeScript type positions?

In TypeScript, typeof can be used in type positions to capture the type of a variable or function. Different from JavaScript runtime typeof.

Example
const config = { host: "localhost", port: 3000 };\ntype Config = typeof config; // { host: string; port: number }\n\nfunction createUser(name: string, age: number) { return { name, age }; }\ntype User = ReturnType<typeof createUser>; // { name: string; age: number }
18

What are template literal types?

Template literal types build string types by combining string literals, similar to JavaScript template literals.

Example
type EventName = "click" | "focus" | "blur";\ntype Handler = `on${Capitalize<EventName>}`; // "onClick" | "onFocus" | "onBlur"\n\ntype CSSProperty = `${string}-${string}`;\nconst prop: CSSProperty = "background-color"; // OK
19

What is strict mode in TypeScript?

Enabling "strict": true in tsconfig.json activates a set of strict type-checking options.

  • strictNullChecks - null and undefined are not assignable to other types.
  • noImplicitAny - error when TypeScript infers any.
  • strictFunctionTypes - stricter checking of function parameter types.
  • strictPropertyInitialization - class properties must be initialized in constructor.
Example
// tsconfig.json\n{\n  "compilerOptions": {\n    "strict": true,\n    "target": "ES2022",\n    "module": "ESNext"\n  }\n}
20

What is declaration merging?

Declaration merging combines multiple declarations with the same name into a single definition. Works with interfaces, namespaces, and enums.

Example
interface Window { myPlugin: () => void; }\n// Merges with the built-in Window interface\n// Now window.myPlugin is type-safe\n\n// Augmenting a module\ndeclare module "express" {\n  interface Request { user?: { id: number; role: string }; }\n}
21

What is the difference between abstract class and interface?

  • Abstract class - can have implemented methods, constructors, and state. A class can extend only one.
  • Interface - only declarations (no implementation). A class can implement multiple interfaces.
  • Use abstract class when sharing implementation; use interface for defining contracts.
Example
abstract class Animal {\n  abstract speak(): string;\n  breathe() { return "breathing"; } // concrete method\n}\n\ninterface Flyable { fly(): void; }\ninterface Swimmable { swim(): void; }\nclass Duck extends Animal implements Flyable, Swimmable { ... }
22

What are index signatures?

Index signatures allow defining types for objects with dynamic keys.

Example
interface StringMap { [key: string]: string; }\nconst headers: StringMap = { "Content-Type": "application/json" };\n\ninterface Config {\n  timeout: number;\n  [key: string]: number; // all values must be number\n}
23

What is the infer keyword?

infer is used inside conditional types to capture and reuse a type within the condition. It is how ReturnType and Parameters utility types are implemented.

Example
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;\ntype Parameters<T> = T extends (...args: infer P) => any ? P : never;\n\nfunction greet(name: string): string { return `Hello ${name}`; }\ntype R = ReturnType<typeof greet>; // string\ntype P = Parameters<typeof greet>; // [name: string]
24

What is module augmentation?

Module augmentation extends existing module types without modifying the original source. Useful for adding types to third-party libraries.

Example
// Extend Express Request type\nimport "express";\ndeclare module "express" {\n  interface Request {\n    user?: { id: number; role: string };\n  }\n}\n// Now req.user is type-safe in all Express handlers
25

What is the difference between .ts and .d.ts files?

  • .ts - regular TypeScript source files. Contain implementation code that compiles to JavaScript.
  • .d.ts - declaration files. Contain only type information (no implementation). Used to type JavaScript libraries.
  • Generated automatically with tsc --declaration or written manually for JS libraries.
26

What is the difference between type assertion and type casting?

  • Type assertion (as Type or ) - tells TypeScript to treat a value as a specific type. No runtime effect. Can be unsafe.
  • Type casting - actual runtime conversion (e.g., Number("42")). TypeScript has no built-in casting; use type assertions for compile-time only.
Example
const input = document.getElementById("name") as HTMLInputElement;\nconst value = (input as HTMLInputElement).value;\n\n// Double assertion for incompatible types\nconst x = "hello" as unknown as number; // unsafe!
27

What is the difference between Exclude and Extract utility types?

  • Exclude - removes types from T that are assignable to U.
  • Extract - keeps only types from T that are assignable to U.
Example
type T = string | number | boolean;\ntype NoBoolean = Exclude<T, boolean>; // string | number\ntype OnlyString = Extract<T, string>; // string\n\ntype NonNullable<T> = Exclude<T, null | undefined>;
28

What is the difference between interface and type for function signatures?

  • Both can describe function types.
  • interface uses call signature syntax.
  • type uses arrow function syntax.
  • Both are equivalent for function types.
Example
// Interface call signature\ninterface Formatter {\n  (value: string, options?: object): string;\n}\n\n// Type alias\ntype Formatter = (value: string, options?: object) => string;\n\n// Both work the same way\nconst fmt: Formatter = (v) => v.trim();
29

What is the difference between readonly array and regular array?

  • readonly T[] or ReadonlyArray - cannot push, pop, or mutate. Compile-time only.
  • T[] - mutable array.
  • Use readonly arrays for function parameters to prevent accidental mutation.
Example
function sum(nums: readonly number[]): number {\n  // nums.push(1); // Error: push does not exist on readonly\n  return nums.reduce((a, b) => a + b, 0);\n}\n\nconst arr: ReadonlyArray<number> = [1, 2, 3];
30

What is the difference between namespace and module in TypeScript?

  • Module (ES module) - file-based. Uses import/export. The modern standard. Preferred.
  • Namespace - TypeScript-specific. Uses namespace keyword. Useful for organizing code in global scripts or declaration files.
  • Avoid namespaces in modern TypeScript projects that use modules.
Example
// Namespace (legacy)\nnamespace Utils {\n  export function format(s: string) { return s.trim(); }\n}\nUtils.format("hello");\n\n// Module (modern)\nexport function format(s: string) { return s.trim(); }
31

What is the difference between overloads and union types for function signatures?

  • Union types - simpler. Single implementation handles all types.
  • Function overloads - provide multiple specific signatures. Better for complex type relationships where return type depends on input type.
Example
// Overloads\nfunction process(x: string): string;\nfunction process(x: number): number;\nfunction process(x: string | number): string | number {\n  return typeof x === "string" ? x.toUpperCase() : x * 2;\n}
32

What is the difference between type widening and narrowing?

  • Type widening - TypeScript infers a broader type from a literal. let x = "hello" infers string, not "hello".
  • Type narrowing - TypeScript refines a broad type to a specific one using type guards (typeof, instanceof, in, discriminant).
  • Use as const to prevent widening: const x = "hello" as const infers "hello" (literal type).
Example
let x = "hello";        // widened to string\nconst y = "hello";      // literal type "hello"\nconst z = "hello" as const; // literal type "hello"\n\nconst arr = [1, 2, 3] as const; // readonly [1, 2, 3]
33

What is the difference between Pick and Omit?

  • Pick - creates a type with only the specified keys from T.
  • Omit - creates a type with all keys from T except the specified ones.
  • Both are useful for creating subset types from larger interfaces.
Example
interface User { id: number; name: string; email: string; password: string; }\n\ntype PublicUser = Omit<User, "password">; // id, name, email\ntype UserCredentials = Pick<User, "email" | "password">; // email, password
34

What is the difference between Parameters and ReturnType utility types?

  • Parameters - extracts the parameter types of a function as a tuple.
  • ReturnType - extracts the return type of a function.
  • Both use the infer keyword internally.
Example
function createUser(name: string, age: number, role: string) {\n  return { name, age, role };\n}\n\ntype Params = Parameters<typeof createUser>; // [string, number, string]\ntype Result = ReturnType<typeof createUser>;  // { name: string; age: number; role: string }
35

What is the difference between InstanceType and ConstructorParameters?

  • InstanceType - extracts the instance type of a constructor function/class.
  • ConstructorParameters - extracts the constructor parameter types as a tuple.
Example
class User {\n  constructor(public name: string, public age: number) {}\n}\n\ntype UserInstance = InstanceType<typeof User>; // User\ntype UserParams = ConstructorParameters<typeof User>; // [string, number]
36

What is the difference between Awaited and Promise in TypeScript?

  • Promise - represents a pending async operation that resolves to T.
  • Awaited (TS 4.5+) - recursively unwraps Promise types. Awaited> = string. Awaited>> = number.
Example
type A = Awaited<Promise<string>>;           // string\ntype B = Awaited<Promise<Promise<number>>>;   // number\ntype C = Awaited<string>;                     // string (non-Promise passthrough)\n\nasync function fetchUser(): Promise<User> { ... }\ntype FetchResult = Awaited<ReturnType<typeof fetchUser>>; // User
37

What is the difference between type-only imports and regular imports?

  • import type { T } - imports only the type. Erased at compile time. Cannot be used as a value.
  • import { T } - imports the value. Kept in compiled output if used as a value.
  • Use import type for types to improve build performance and avoid circular dependency issues.
Example
import type { User } from "./types"; // type-only, erased at runtime\nimport { createUser } from "./utils"; // value import, kept\n\n// TypeScript 5.0+ inline type imports\nimport { type User, createUser } from "./module";
38

What is the difference between satisfies and as const?

  • as const - makes all values literal types and readonly. No type validation.
  • satisfies - validates the value against a type while preserving the most specific type. Does not widen types.
Example
const config = {\n  port: 3000,\n  host: "localhost"\n} as const; // { readonly port: 3000; readonly host: "localhost" }\n\nconst config2 = {\n  port: 3000,\n  host: "localhost"\n} satisfies { port: number; host: string };\n// port is still 3000 (literal), not number
39

What is the difference between TypeScript project references and regular imports?

  • Regular imports - all files compiled together. Slow for large projects.
  • Project references (tsconfig references) - split large projects into smaller sub-projects. Incremental compilation. Faster builds.
  • Used in monorepos and large codebases.
Example
// tsconfig.json\n{\n  "references": [\n    { "path": "./packages/core" },\n    { "path": "./packages/ui" }\n  ]\n}
40

What is the difference between TypeScript strict null checks and optional chaining?

  • strictNullChecks - compiler option that makes null and undefined separate types. Forces you to handle them explicitly.
  • Optional chaining (?.) - runtime operator that short-circuits to undefined if a value is null/undefined.
  • Both work together: strictNullChecks catches potential null access at compile time; ?. handles it at runtime.
Example
// With strictNullChecks\nfunction getCity(user: User | null): string | undefined {\n  return user?.address?.city; // optional chaining\n}
41

What is the difference between TypeScript path aliases and relative imports?

  • Relative imports (./utils) - explicit path. Works everywhere. Can become verbose in deep directory structures.
  • Path aliases (@/utils) - configured in tsconfig.json paths. Cleaner imports. Requires bundler configuration to resolve.
Example
// tsconfig.json\n{\n  "compilerOptions": {\n    "paths": { "@/*": ["./src/*"] }\n  }\n}\n\n// Usage\nimport { formatDate } from "@/utils/date"; // instead of "../../../utils/date"
42

What is the difference between TypeScript 4.x and 5.x features?

  • TS 4.0 - variadic tuple types, labeled tuple elements.
  • TS 4.1 - template literal types, key remapping in mapped types.
  • TS 4.5 - Awaited type, type-only imports in regular imports.
  • TS 4.9 - satisfies operator, auto-accessors.
  • TS 5.0 - decorators (standard), const type parameters.
  • TS 5.1 - unrelated types for setters/getters.
  • TS 5.2 - using declarations (explicit resource management).
43

What is the using declaration in TypeScript 5.2?

The using declaration (TypeScript 5.2, ECMAScript proposal) automatically disposes resources when they go out of scope, similar to C# using or Python with. The resource must implement Symbol.dispose.

Example
class DatabaseConnection {\n  [Symbol.dispose]() { this.close(); }\n  close() { console.log("Connection closed"); }\n}\n\n{\n  using conn = new DatabaseConnection();\n  // use conn...\n} // conn.close() called automatically here
44

What is the difference between TypeScript const type parameters and regular type parameters?

Const type parameters (TS 5.0) infer literal types instead of widened types, similar to as const but for generic functions.

Example
// Without const: T inferred as string[]\nfunction identity<T>(arr: T): T { return arr; }\nidentity(["a", "b"]); // string[]\n\n// With const: T inferred as ["a", "b"]\nfunction identity<const T>(arr: T): T { return arr; }\nidentity(["a", "b"]); // readonly ["a", "b"]
45

What is the difference between TypeScript declaration files for CommonJS and ESM?

  • CommonJS declaration - uses module.exports = ... or export = .... Requires esModuleInterop for default imports.
  • ESM declaration - uses export default and named exports. Modern standard.
  • Use "moduleResolution": "bundler" or "node16" in tsconfig for correct ESM resolution.
Example
// CommonJS .d.ts\ndeclare module "my-lib" {\n  export function helper(): void;\n  export default class MyLib { ... }\n}\n\n// ESM .d.ts\nexport function helper(): void;\nexport default class MyLib { ... }
46

What is the difference between TypeScript strict mode options?

  • strict: true enables all strict options at once.
  • strictNullChecks - null/undefined are separate types.
  • strictFunctionTypes - contravariant function parameter checking.
  • strictBindCallApply - strict types for bind/call/apply.
  • strictPropertyInitialization - class properties must be initialized.
  • noImplicitAny - error on implicit any.
  • noImplicitThis - error on implicit this.
  • alwaysStrict - emit "use strict" in output.
47

What is the difference between TypeScript enums and const enums?

  • Regular enum - compiled to a JavaScript object. Can be iterated. Supports reverse mapping for numeric enums.
  • const enum - inlined at compile time. No JavaScript object generated. Cannot be iterated. Smaller bundle.
  • Avoid const enum in declaration files (.d.ts) as they cause issues with isolated modules.
Example
enum Color { Red, Green, Blue } // compiled to JS object\nconst enum Direction { Up, Down } // inlined: Direction.Up becomes 0\n\n// Reverse mapping (numeric enums only)\nColor[0]; // "Red"
48

What is the difference between TypeScript abstract methods and regular methods?

  • Abstract method - declared in abstract class with no implementation. Subclasses must implement it.
  • Regular method - has an implementation. Can be overridden but does not have to be.
  • Abstract classes cannot be instantiated directly.
Example
abstract class Shape {\n  abstract area(): number; // must implement\n  toString() { return `Area: ${this.area()}`; } // concrete\n}\n\nclass Circle extends Shape {\n  constructor(private r: number) { super(); }\n  area() { return Math.PI * this.r ** 2; } // required\n}
49

What is the difference between TypeScript type guards and assertion functions?

  • Type guard (is keyword) - a function that returns a boolean and narrows the type if true.
  • Assertion function (asserts keyword) - throws if condition is false. Narrows the type after the call.
Example
// Type guard\nfunction isString(val: unknown): val is string {\n  return typeof val === "string";\n}\n\n// Assertion function\nfunction assertString(val: unknown): asserts val is string {\n  if (typeof val !== "string") throw new Error("Not a string");\n}\n\nassertString(value); // value is string after this line
50

What is the difference between TypeScript accessor keyword and get/set?

The accessor keyword (TS 4.9+) is shorthand for defining a class field with auto-generated getter and setter. It is cleaner than manually writing get/set pairs.

Example
// Traditional get/set\nclass User {\n  private _name = "";\n  get name() { return this._name; }\n  set name(v: string) { this._name = v; }\n}\n\n// accessor keyword (TS 4.9+)\nclass User {\n  accessor name = ""; // auto-generates get/set\n}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.