YouTube Summaries | TypeScript Generics are Easy Once You Know This

October 22nd, 2023

TL:DW - “Generics in TypeScript Functions and React Components”

  • Generics play a crucial role in maintaining a strong and clear relationship between input and output data in functions.
  • Generics in React components allow for the creation of reusable and type-safe components.
  • Generic types for component props ensure type consistency.
  • They enable the creation of versatile and reusable functions and components that can handle various data types without sacrificing type consistency.

Generics in TypeScript Functions

You can use generics in TypeScript functions to create more flexible and type-safe code. Generics allow you to work with various data types while retaining type information.

The following example of a generic function convertToArray:

function convertToArray<T>(input: T): T[] {
  return [input];
}

const numArray = convertToArray(5); // TypeScript infers numArray as number[]
const strArray = convertToArray("hello"); // TypeScript infers strArray as string[]

Additionally, TypeScript allows you to restrict a generic type to a specific input type using the extends keyword as below:

function convertToArray<T extends string | number>(input: T): T[] {
  return [input];
}

const numArray = convertToArray(42); // Returns: [42]
const strArray = convertToArray("hello"); // Returns: ["hello"]

// This will result in a TypeScript error since it doesn't match the restricted types.
// const boolArray = convertToArray(true); // Error: Argument of type 'true' is not assignable to parameter of type 'string | number'.

Generics in React Components

Generics are also valuable in creating reusable React components. You can define generic types for component props, allowing for type-safe components with varying data types.

Here’s an example of a theme-switching component that uses generics:

import React from "react";

type Theme = "light" | "dark" | "system";

type ThemeSwitcherProps<T> = {
  themeOptions: T[];
  selectedTheme: T;
  onThemeClick: (theme: T) => void;
};

function ThemeSwitcher<T>({
  themeOptions,
  selectedTheme,
  onThemeClick,
}: ThemeSwitcherProps<T>): JSX.Element {
  return (
    <div>
      {themeOptions.map((theme) => (
        <button key={theme} onClick={() => onThemeClick(theme)}>
          {theme}
        </button>
      ))}
      <p>Selected Theme: {selectedTheme}</p>
    </div>
  );
}

const themes: Theme[] = ["light", "dark", "system"];

export const App = () => {
  const [selectedTheme, setSelectedTheme] = React.useState(themes[0]);

  return (
    <ThemeSwitcher
      themeOptions={themes}
      selectedTheme={selectedTheme}
      onThemeClick={setSelectedTheme}
    />
  );
};