Eric Nishio

What the Heck Are All the <T>s in TypeScript?


If you’re relatively new to TypeScript or typed programming languages in general, the <T> annotation may seem confusing.

They’re called generic type variables (or generics for short) and they’re actually really handy by letting you define a variable within a type. The name T (for type) is just a common naming pattern, but it can really be anything.

Imagine writing a dropdown component that accepts different option types. For example, one page might show a list of languages and another one years. Instead of having to enumerate all the possible value types in the generic component itself, we can declare a generic type that can be freely specified when consuming the component.

Think of it as a function argument that you pass to a type and reference it within the type declaration:

interface Option<T> {
  label: string
  value: T

When we make the dropdown options generic, we can document our code more precisely while keeping the reusable code generic and letting the consumer decide what the implementation details are:

const languageOptions: Option<string> = [
  { label: 'American', value: 'en-US' },
  { label: 'Finnish', value: 'fi-FI' },
  { label: 'Japanese', value: 'ja-JP' },

const yearOptions: Option<number> = [
  { label: '1985', value: 1985 },
  { label: '1988', value: 1988 },

Generics can be primitives like strings, numbers, and booleans, or entire interfaces!

Here’s how you’d use generics in a function:

interface Struct<T> {
  value: T

function createStruct<T>(value: T): Struct<T> {
  return {

Then you can use this function by explicitly specifying a type for T:

const withNumber = createStruct<number>(200)
const withString = createStruct<string>('hello')

Or you can let the TypeScript compiler automatically infer the type based on what arguments you feed it:

const withNumber = createStruct(200)
const withString = createStruct('hello')
Japanese Wax Seal: NishioCopyright 2024 Eric Nishio