JSTAcademy
0 XP
Dashboard
Crash Courses
Generics
11 min
Masters+175 XP
Crash Courses · Masters

Generics

Write reusable, type-safe functions and components that work across multiple types.
11 min read+175 XP on completionCert: TypeScript Crash Course
Tap any word in the text below to start reading from there.

Generics

Generics let you write one function or interface that works with many types without sacrificing type safety.

Why Generics

// Without generics — duplicate for each type
function getFirstStr(arr: string[]): string { return arr[0] }
function getFirstNum(arr: number[]): number { return arr[0] }

// With generics — one function
function getFirst<T>(arr: T[]): T {
  return arr[0]
}

const name = getFirst(['Jordan', 'Owen'])  // T = string
const score = getFirst([100, 95, 87])       // T = number

Generic API Response Interface

interface ApiResponse<T> {
  data: T
  error: string | null
  status: number
}

interface Paginated<T> {
  items: T[]
  total: number
  page: number
}

async function fetchUser(id: string): Promise<ApiResponse<User>> {
  const res = await fetch(`/api/users/${id}`)
  return res.json()
}

Generic Constraints

interface HasId { id: string }

function findById<T extends HasId>(items: T[], id: string): T | undefined {
  return items.find(item => item.id === id)
}

const user = findById(users, 'user_001')     // T = User
const course = findById(courses, 'cc-ts-m01') // T = Course

Generic React Components

interface ListProps<T> {
  items: T[]
  renderItem: (item: T) => React.ReactNode
  keyExtractor: (item: T) => string
}

function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
  return (
    <ul>
      {items.map(item => (
        <li key={keyExtractor(item)}>{renderItem(item)}</li>
      ))}
    </ul>
  )
}
0%