Skip to content

Instantly share code, notes, and snippets.

@3ZsForInsomnia
Created January 11, 2020 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 3ZsForInsomnia/81d80ece0e31361440592195e764ce71 to your computer and use it in GitHub Desktop.
Save 3ZsForInsomnia/81d80ece0e31361440592195e764ce71 to your computer and use it in GitHub Desktop.
Exploring a ts article on scala's pattern matching and another approach
interface IShape {
area: number;
sayHi(...args: any[]): string;
type: string;
}
interface Circle extends IShape {
type: 'circle';
}
interface Rectangle extends IShape {
type: 'rectangle';
}
interface Square extends IShape {
type: 'square';
}
type Shape = Square | Circle | Rectangle;
type ShapeType = Shape['type'];
type ShapeMap<UKind> = { [KShapeType in ShapeType]: UKind extends { type: KShapeType } ? UKind : never }
type ShapeTypeMap = ShapeMap<Shape>;
// type Pattern<TKind, TMap> = { [K in keyof TMap]: (shape: TMap[K]) => TKind}
// function matcher<T>(pattern: Pattern<T, ShapeTypeMap>): (shape: Shape) => T {
// return shape => pattern[shape.type](shape as any);
// }
const myRectangle = {
type: 'rectangle',
sayHi: (arg: string) => `its a ${arg}`,
area: 5
}
const mySquare = {
type: 'square',
sayHi: () => 'its a square',
area: 9
}
const shapeMatcher = (shape: IShape, ...args: any[]) => {
switch (shape.type) {
case 'rectangle':
return shape.sayHi(...args);
default:
break;
}
return 'not found';
}
console.log(shapeMatcher(myRectangle, 'it works'));
console.log(shapeMatcher(mySquare));
interface matchable {
type: string;
}
const NewShapeMap = {
rectangle: true,
circle: true,
square: true
}
const matcher = <TShape extends matchable, TFunc extends keyof TShape>(map: {[key: string]: any}, func: TFunc) => (obj: TShape) => (...args: any[]) =>
map[obj.type] ? (obj[func] as any)(...args) : null;
const shapeMatcher2 = matcher<IShape, 'sayHi'>(NewShapeMap, 'sayHi');
console.log(shapeMatcher2(myRectangle)('its a rectangle'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment