TypeScript

Top 20 Advanced TypeScript Interview Questions and Answers

1. What is the key difference between “interface” and “type” in TypeScript?

  • Both interface and type are used to define custom types, but they have subtle differences.
  • interface is more suitable for declaring object shapes, while type is more versatile and can be used for unions, intersections, and mapped types.

Code Example:

interface Car {
  brand: string;
  model: string;
}

type Bike = {
  brand: string;
  model: string;
};

2. What are mapped types in TypeScript?

  • Mapped types allow you to create new types by transforming each property in an existing type.
  • Commonly used mapped types include Partial, Readonly, and Record.

Code Example:

type OptionalCar = Partial<Car>; // Makes all properties in Car optional
type ImmutableCar = Readonly<Car>; // Makes all properties in Car readonly

3. What is the “keyof” keyword in TypeScript?

  • keyof is a keyword that produces a union type of all the property names of a given type.
  • Useful for creating dynamic property access or enforcing constraints on object keys.

Code Example:

type CarKey = keyof Car; // "brand" | "model"

4. Explain conditional types in TypeScript.

  • Conditional types allow you to create types that depend on other types.
  • Uses the extends keyword to create branches based on type conditions.

Code Example:

type IsConvertible<T> = T extends { convertible: true } ? "Yes" : "No";

type SportsCar = { brand: string; model: string; convertible: true };
type Sedan = { brand: string; model: string; convertible: false };

const sportsCarResult: IsConvertible<SportsCar> = "Yes"; // "Yes"
const sedanResult: IsConvertible<Sedan> = "No"; // "No"

5. How does TypeScript support mixin patterns?

  • Mixins are a way to compose classes from multiple sources.
  • TypeScript leverages intersection types to combine the functionalities of different classes.

Code Example:

class Engine {
  start() {
    console.log("Engine started");
  }
}

class Wheels {
  roll() {
    console.log("Wheels rolling");
  }
}

type Car = Engine & Wheels;

const myCar = new Car();
myCar.start(); // "Engine started"
myCar.roll(); // "Wheels rolling"

6. What are decorators in TypeScript?

  • Decorators are a way to add metadata and modify the behavior of classes and class members.
  • Applied using the @decorator syntax, they are commonly used in frameworks like Angular.

Code Example:

function logMethod(target: any, key: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function (...args: any[]) {
    console.log(`Calling ${key} with arguments: ${JSON.stringify(args)}`);
    return originalMethod.apply(this, args);
  };

  return descriptor;
}

class Calculator {
  @logMethod
  add(a: number, b: number): number {
    return a + b;
  }
}

const calculator = new Calculator();
calculator.add(2, 3); // Logs: "Calling add with arguments: [2, 3]"

7. Explain the “never” type in TypeScript.

  • The never type represents values that never occur.
  • Often used for functions that throw exceptions or never return.

Code Example:

function throwError(message: string): never {
  throw new Error(message);
}

function infiniteLoop(): never {
  while (true) {
    // Infinite loop
  }
}

8. What is the “key remapping” feature in mapped types?

  • Key remapping allows you to change the keys of an object type.
  • Uses the as keyword for remapping.

Code Example:

type NewCar = {
  newBrand: string;
  newModel: string;
};

type RemappedCar = {
  [K in keyof Car as `new${K}`]: Car[K];
};

const myRemappedCar: RemappedCar = {
  newBrand: "Toyota",
  newModel: "Camry",
};

9. How does TypeScript support conditional rendering with types?

  • TypeScript can infer types based on conditions to enable conditional rendering.
  • Uses conditional types in combination with React’s JSX.

Code Example:

type Props<T> = {
  value: T;
  render: (value: T) => JSX.Element;
};

function ConditionalRender<T>({ value, render }: Props<T>): JSX.Element {
  return value ? render(value) : <div>No value to render</div>;
}

10. What is “declaration merging” in TypeScript?

  • Declaration merging is a TypeScript feature that allows multiple declarations of the same entity to be combined into a single definition.
  • Commonly used with interfaces and namespaces.

Code Example:

interface Car {
  brand: string;
  model: string;
}

interface Car {
  year: number;
}

const myCar: Car = {
  brand: "Toyota",
  model: "Camry",
  year: 2022,
};

11. Explain the concept of “type guards” in TypeScript.

  • Type guards are expressions that perform runtime checks to narrow down the type of a variable.
  • Commonly used with typeof, instanceof, and custom predicates.

Code Example:

function isNumber(value: any): value is number {
  return typeof value === "number";
}

const myValue: number | string = 42;

if (isNumber(myValue)) {
  // Inside this block, TypeScript knows myValue is a number
  console.log(myValue.toFixed(2));
}

12. How does TypeScript handle enums compared to plain JavaScript?

  • TypeScript enums provide a way to define named numeric constants.
  • Enums in TypeScript are more powerful than plain JavaScript enums as they can be used in both numeric and string forms.

Code Example:

enum Color {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE",
}

const myColor: Color = Color.Green;

13. What is the “Partial” type and how is it useful?

  • The Partial<T> type makes all properties of type T optional.
  • Useful when dealing with optional properties in function arguments or updating partial objects.

Code Example:

type PartialCar = Partial<Car>;

const partialCar: PartialCar = {
  brand: "Toyota",
};

14. Explain the “in” operator in TypeScript.

  • The in operator checks if a property exists in an object.
  • Useful for iterating over object keys or creating conditional logic based on property existence.

Code Example:

const car: Car = {
  brand: "Toyota",
  model: "Camry",
};

if ("brand" in car) {
  console.log("Car has a brand property");
}

15. How can you create a utility type to make properties of an object readonly?

  • Use the Readonly<T> utility type to make all properties of type T readonly.
  • Helpful for preventing accidental modifications to objects.

Code Example:

type ReadonlyCar = Readonly<Car>;

const myReadonlyCar: ReadonlyCar = {
  brand: "Toyota",
  model: "Camry",
};

// Error: Cannot assign to 'brand' because it is a read-only property
myReadonlyCar.brand = "Honda";

16. How does TypeScript handle “this” in functions?

  • TypeScript allows you to specify the type of this in functions using the this parameter.
  • Helps catch potential errors and provides better tooling support.

Code Example:

function greet(this: { name: string }, greeting: string) {
  console.log(`${greeting}, ${this.name}!`);
}

const person = { name: "John" };

greet.call(person, "Hello"); // Logs: "Hello, John!"

17. What is the “unknown” type in TypeScript and how is it different from “any”?

  • The unknown type is safer than any because you cannot perform arbitrary operations on values of type unknown without type assertions.
  • unknown requires type-checking before usage.

Code Example:

let value: unknown;

// Error: Object is of type 'unknown'.
value.toString();

// OK: Type assertion
(value as string).toString();

18. Explain the “as const” assertion in TypeScript.

  • The as const assertion is used to infer literal types for every property in an object or for the values of an array.
  • Helps create immutable objects and narrow down types.

Code Example:

const carOptions = {
  brand: "Toyota",
  model: "Camry",
} as const;

// Error: Cannot assign to 'brand' because it is a read-only property
carOptions.brand = "Honda";

19. How does TypeScript support tuple types?

  • Tuple types allow you to express an array where the type of a fixed number of elements is known.
  • Order and types of elements in a tuple are fixed.

Code Example:

type Point = [number, number];

const coordinates: Point = [3, 4];

20 What is the “never” return type in functions?

  • The never return type indicates that a function never produces a value (either it throws an exception or has an infinite loop).
  • Useful for functions with side effects or exceptional cases.

Code Example:

function throwError(message: string): never {
  throw new Error(message);
}

function infiniteLoop(): never {
  while (true) {
    // Infinite loop
  }
}

“Unveiling the Lesser-Known: 15 Expert TypeScript Interview Queries for 2024”
“Navigating the Depths: Top 25 TypeScript Interview Questions for 2024”
“Mastering TypeScript: A Comprehensive Guide to 2024’s Key Interview Questions”
“2024’s Unexplored Territory: 18 In-Depth TypeScript Interview Challenges”
“Beyond the Basics: Your Go-To Guide for 2024’s Advanced TypeScript Interviews”
“Cracking the Code: 22 Lesser-Explored TypeScript Interview Questions in 2024”
“Dive Deeper: Exploring 2024’s Unique TypeScript Interview Questions”
“Unlocking Success: 21 Essential TypeScript Interview Questions for 2024”
“Elevate Your Prep: 17 Uncommon TypeScript Interview Questions in 2024”
“2024’s TypeScript Insights: Mastering 24 Advanced Interview Questions”

Leave a Reply

Your email address will not be published. Required fields are marked *