Functions and generics

TypeScript generics explained simply

TypeScript generics let functions and types work with many values while keeping type safety. Learn syntax, constraints, and when to skip them.

Generics let you write code that works with many types without throwing away type information. You get one function or type definition, and TypeScript still knows what you passed in.

Why generics exist

Say you want a function that returns the first item of an array.

Without generics you pick one type:

function firstNumber(items: number[]) {
  return items[0]
}

That works for numbers. For strings you copy the function and change the type. That gets old fast.

You could use any:

function first(items: any[]) {
  return items[0]
}

TypeScript stops helping you. You lose autocomplete and compile-time checks.

Generics fix this. You write the function once, and the type follows the argument:

function first<T>(items: T[]) {
  return items[0]
}

const n = first([1, 2, 3])   // number | undefined
const s = first(['a', 'b'])  // string | undefined

The T is a type parameter. TypeScript fills it in when you call the function.

Generic constraints with extends

Sometimes the generic type must have certain properties.

You restrict it with extends:

interface HasName {
  name: string
}

function greet<T extends HasName>(person: T) {
  console.log(`Hi ${person.name}!`)
}

greet({ name: 'Flavio', age: 40 })

This is the same idea from the TypeScript tutorial: generics can be limited to a class family or interface.

Generic types and interfaces

Generics are not just for functions. You can type API responses like this:

type ApiResponse<T> = {
  data: T
  status: number
}

type User = { id: number, name: string }

const res: ApiResponse<User> = {
  data: { id: 1, name: 'Flavio' },
  status: 200
}

You write ApiResponse once. Swap User for any other type.

Arrays use the same pattern:

const nums: Array<number> = [1, 2, 3]

Array<number> is a generic type. The number inside the angle brackets is the type argument.

When not to use generics

My advice is to skip generics when a plain type works.

If your function only ever handles strings, type it as string[]. No generic needed.

If you reach for generics on the first version of a helper, you might be over-engineering. Start simple. Add a generic when you actually need the same logic for a second type.

Generics shine in reusable utilities, API wrappers, and libraries. For a one-off function in your app, a concrete type is often enough.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →