type Adder = (a: T, b: T) => T; function makeAdder(): Adder { return (a: T, b: T): T => { return a + b; }; } var i32Adder = makeAdder(); assert(i32Adder(1, 2) == 3); var i64Adder = makeAdder(); assert(i64Adder(10, 20) == 30); assert(makeAdder()(1.5, 2.5) == 4.0); function doAddWithFn(a: T, b: T, fn: (a: T, b: T) => T): T { return fn(a, b); } assert(doAddWithFn(2, 3, i32Adder) == 5); function doAdd(a: T, b: T): T { return makeAdder()(a, b); } assert(doAdd(3, 4) == 7); function addI32(a: i32, b: i32): i32 { return a + b; } assert(doAddWithFn(4, 5, addI32) == 9); function makeAndAdd(a: T, b: T, adder: Adder = makeAdder()): T { return adder(a, b); } assert(makeAndAdd(1, 2) == 3); assert(makeAndAdd(1, 2, makeAdder()) == 3);