Course outline · 0% complete

0/26 lessons0%

Course overview →

Your First Generic Function

lesson 6-1 · ~11 min · 18/26

Quiz

Warm-up from lesson 2-3: you need firstOf(items) to work on both number[] and string[]. Why is typing items as any[] a bad fix?

The problem generics solve

Here is a function that works for any element type:

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

For strings you would need a copy with string[]. Copies for every type, all identical bodies. The any escape hatch kills checking. What you want to say is: "this works for some type, call it T, and whatever array of T comes in, one T comes out".

That is exactly a generic function:

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

<T> declares a type parameter, a placeholder filled in at each call. Call it with [10, 20, 30] and T becomes number for that call. Call it with strings and T becomes string. One body, full checking, no copies.

firstOf<>(items)numberfirstOf([10, 20, 30]) → T = numberstringfirstOf(["alpha", "beta"]) → T = stringthe T slot is filled in at each call site
A generic function has a slot. Each call fills the slot with a concrete type, inferred from the argument.

Code exercise · typescript

Run it. n is a number and s is a string, both inferred, which is why n + 5 and s.toUpperCase() both compile. Then try firstOf([1, 2]).toUpperCase() to see checking survive.

Code exercise · typescript

Your turn. Write lastOf<T>(items: T[]): T returning the last element (index items.length - 1). Print lastOf([1, 2, 3]), then lastOf(["x", "y", "z"]).toUpperCase().