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%