Course outline · 0% complete

0/26 lessons0%

Course overview →

Typing Callbacks

lesson 5-2 · ~11 min · 16/26

Functions as values need types too

In Advanced JavaScript you passed functions to map, filter, and event handlers. A function type describes such a value: its parameters and its return type, written with an arrow.

function applyTwice(value: number, fn: (n: number) => number): number {
  return fn(fn(value));
}

Read (n: number) => number as "a function that takes a number and returns a number". Now the compiler checks both sides of the deal:

  • Passing (n) => n + 1 is fine
  • Passing (s: string) => s is an error, wrong parameter type
  • Inside the body, calling fn(true) is an error too

The callback bugs you debugged by hand in JavaScript become one-line compile errors.

Code exercise · typescript

Run it. Then try applyTwice(5, (s: string) => s) to see the mismatch reported at the call site instead of exploding inside.

5fn(5) = 6fn(6) = 77applyTwice(5, fn) where fn: (n: number) => numberthe function type guarantees each step takes and returns a number
applyTwice feeds the value through the callback twice. The function type (n: number) => number checks every hop.

Contextual typing: the callback knows its own types

Notice (n) => n + 1 needed no annotation on n. TypeScript already knows the expected callback type from applyTwice, so it types n as number from context. This is contextual typing, and it is why array methods feel so smooth:

const prices: number[] = [3, 10, 6];
const labels = prices.map((p) => "$" + p);

p is automatically number because prices is number[], and labels is inferred as string[] because the callback returns strings. The same map, filter, and reduce you know, now with every step checked.

Code exercise · typescript

Run it and hover nothing: p and sum are typed entirely from context. Then change "$" + p to p.toUpperCase() and run to see the compiler catch it.

Code exercise · typescript

Your turn. Define type WordRule = (word: string) => boolean. Write countMatching(items: string[], rule: WordRule): number that counts items where rule(item) is true. With animals = ["cat", "horse", "dog", "elephant"], print the count of words with length <= 3, then the count of words whose first character (charAt(0)) is "h".