DEV3 Technologies home

DEV3 Developer Forum

How do generics work in TypeScript? I do not understand `<T>`.

JavaScript helpSolved0 views
dev3 ·

I see functions like function first<T>(arr: T[]): T and Promise<User>. What problem do generics solve and how do I constrain them?

#typescript#generics

0

1 reply

dev3 · Accepted answer

Generics let a function, type or class work with many types while keeping the relationship between input and output types.

Without generics

function first(arr: any[]): any { return arr[0]; }   // loses information

With generics

function first<T>(arr: T[]): T | undefined {
  return arr[0];
}
const n = first([1, 2, 3]);       // number | undefined
const s = first(['a', 'b']);      // string | undefined

T is a type parameter inferred from the argument. You can also pass it explicitly: first<number>([1]).

Constraints

function getLength<T extends { length: number }>(x: T): number {
  return x.length;
}
getLength('abc');     // ok
getLength(42);        // error

keyof for safe property access

function pick<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}
pick({ id: 1, name: 'a' }, 'name');   // string
pick({ id: 1 }, 'nope');              // compile error

Generic types and defaults

type ApiResponse<T = unknown> = { data: T; error?: string };
type Page<T> = { items: T[]; total: number };

async function get<T>(url: string): Promise<ApiResponse<T>> {
  const res = await fetch(url);
  return res.json();
}
const r = await get<Page<User>>('/api/users');

Note that res.json() is unchecked: the generic is a promise to the compiler, not validation.

Built-in generic helpers

Partial<T>, Required<T>, Pick<T, K>, Omit<T, K>, Record<K, V>, ReturnType<typeof fn>, Awaited<T>.

Pitfalls

  • Do not add a generic that appears only once in the signature; it adds nothing.
  • Prefer inference; annotate only when inference fails.
  • In .tsx files arrow generics need a trailing comma or constraint: <T,>(x: T) => x.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.