stackademic

The leading education platform for anyone with an interest in software development.

TypeScript Generics

Write reusable functions and types that work across type parameters

Overview

Generics let you parameterize types. A generic function or interface works with multiple types while preserving type relationships—avoiding any and unsafe casts.

Syntax / Usage

function identity<T>(value: T): T {
  return value
}

const n = identity(42)       // number
const s = identity('hello')  // string

// Multiple type parameters
function pair<A, B>(a: A, b: B): [A, B] {
  return [a, b]
}

// Constrained generics
interface HasId { id: string }

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

// Generic interface
interface ApiResult<T> {
  data: T
  error: string | null
}

Examples

Generic React props:

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>
  )
}

Factory with default type:

function createStore<T = string>(initial: T) {
  let state = initial
  return {
    get: () => state,
    set: (value: T) => { state = value },
  }
}

Common Mistakes

  • Over-genericizing simple functions that only use one type
  • Forgetting constraints when accessing properties on T
  • Using generics when a union or overload is simpler
  • Inference failures—annotate call sites when needed

See Also

interfaces utility-types unions type-guards