Hone

Lessons · TypeScript · the type names the edge

The type names the edge; the test proves it

A return type of number | undefined or number | null admits the empty case out loud, forces every caller to handle it, and gives the test a case to prove.

Hone is a place to practise programming. This is one of its lessons, written out in full and free to read without an account.

What it is for

xs.reduce((a, b) => a + b) compiles on number[] and throws on []; the types are satisfied and the value is not. That gap is exactly what tests at the edges fill.

How to think about it

Ask what the smallest input is and put its answer in the type: undefined, null, or a chosen number. Then test nothing, one, and everything the same.

Worked example

function check(ok: boolean, msg: string): void { if (!ok) throw new Error(msg); }
function head(xs: number[]): number | undefined { return xs[0]; }
The type admits the empty case.
check(head([]) === undefined, 'nothing gives undefined');
Nothing.
check(head([7]) === 7, 'one gives it');
One.
const n = head([5, 5, 5]);
Everything the same.
console.log(n === undefined ? 'empty' : n * 2);
10: the caller handled the case the type forced.

Your turn

Admit the empty case in the type.

function last(xs: number[]): number |  { return xs[xs.length - 1]; }

The trap

const n: number = head([]). The compiler refuses it, because the type said undefined can happen, and the test is what shows you when.

Practise the type names the edge on HoneA question on it now, a coding challenge where there is one, and it is remembered for review. Free, no email needed.