|
You can generalize this with TS's fancy mapped types: type Sum<K> = <T> (cases: Pattern<K, T>) => T
type Pattern<K, T> = {
[V in keyof K]: K[V] extends any[] ? (...args: K[V]) => T : never
}
which takes TS very close to ML: type Shape = Sum<{
circle: [number, number, number],
rectangle: [number, number, number, number]
}>
function Circle(x: number, y: number, r: number): Shape {
return ({ circle }) => circle(x, y, r);
}
function Rectangle(x: number, y: number, w: number, h: number): Shape {
return ({ rectangle }) => rectangle(x, y, w, h);
}
function area(shape: Shape): number {
return shape({
circle: (x, y, r) => Math.PI * r * r,
rectangle: (x, y, w, h) => w * h
});
}
|