Flashcard Deck · 25 cards · Public

TypeScript - Advanced Type Systems, Generics & Design Patterns

Master advanced TypeScript features like generics, conditional types, and mapped types to build robust, scalable applications. This deck covers essential utility types, type narrowing techniques, discriminated unions, and the nuances between interfaces and type aliases, empowering you to write highly maintainable and type-safe code.

Cards in this deck

(25 cards)

Preview terms and definitions before starting your study session.

#1
Term
What are Generics in TypeScript and why are they useful?
Definition
Generics allow you to write components that can work with a variety of types rather than a single one. They provide a way to make components reusable and type-safe by capturing the type of the arguments that are passed in, ensuring type consistency across different parts of the component without sacrificing flexibility.
Example: A function that returns the first element of an array, regardless of the array's element type.
#2
Term
Write a generic function getFirstElement that takes an array of any type and returns the first element, or undefined if the array is empty.
Definition
typescript7 lines
function getFirstElement<T>(arr: T[]): T | undefined {
  return arr.length > 0 ? arr[0] : undefined;
}

// Usage:
const numbers = getFirstElement([1, 2, 3]); // numbers is type number | undefined
const strings = getFirstElement(['a', 'b']); // strings is type string | undefined
#3
Term
Define a generic interface Box<T> that can hold an item of any specified type T.
Definition
typescript7 lines
interface Box<T> {
  value: T;
}

// Usage:
const stringBox: Box<string> = { value: 'Hello' };
const numberBox: Box<number> = { value: 123 };
#4
Term
Explain Type Narrowing in TypeScript and provide an example.
Definition
Type narrowing is the process by which TypeScript refines the type of a variable within a certain code block. This is typically done using conditional checks (type guards) that allow TypeScript to infer a more specific type for the variable, enabling safer operations.
Example:
typescript9 lines
function printId(id: string | number) {
  if (typeof id === 'string') {
    // id is narrowed to 'string' here
    console.log(id.toUpperCase());
  } else {
    // id is narrowed to 'number' here
    console.log(id.toFixed(2));
  }
}
#5
Term
How does the typeof operator act as a type guard?
Definition
The typeof operator is a built-in JavaScript operator that returns a string indicating the type of the unevaluated operand. In TypeScript, it acts as a type guard for primitive types ('string', 'number', 'boolean', 'symbol', 'undefined', 'bigint'). When used in a conditional block, TypeScript narrows the type of the variable accordingly.
Example: if (typeof value === 'string') { /* value is string */ }
#6
Term
How does the instanceof operator act as a type guard?
Definition
The instanceof operator is a built-in JavaScript operator that checks if an object is an instance of a particular class. In TypeScript, it acts as a type guard for class instances. If the condition value instanceof MyClass is true, TypeScript narrows the type of value to MyClass within that block.
Example:
typescript10 lines
class Dog { bark() {} }
class Cat { meow() {} }

function makeSound(animal: Dog | Cat) {
  if (animal instanceof Dog) {
    animal.bark(); // animal is narrowed to Dog
  } else {
    animal.meow(); // animal is narrowed to Cat
  }
}
#7
Term
What are Discriminated Unions and how do they enhance type safety?
Definition
Discriminated unions are a powerful pattern in TypeScript that combine union types with a common, literal property (the 'discriminant'). This discriminant property allows TypeScript to narrow down the specific type within the union based on its value, providing exhaustive type checking and enhancing type safety, especially in switch statements or if/else chains.
Example: Different event types sharing a type property.
#8
Term
Create a discriminated union for different shapes (circle, square) using a kind property.
Definition
typescript20 lines
interface Circle {
  kind: 'circle';
  radius: number;
}

interface Square {
  kind: 'square';
  sideLength: number;
}

type Shape = Circle | Square;

function getArea(shape: Shape): number {
  switch (shape.kind) {
    case 'circle':
      return Math.PI * shape.radius ** 2; // shape is Circle
    case 'square':
      return shape.sideLength ** 2;    // shape is Square
  }
}
Showing 8 of 25 cards in this deck.
Study All Now