Skip to content

Instantly share code, notes, and snippets.

@mweststrate
Created April 14, 2016 14:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mweststrate/d3d6ab3333b886faed6d4f29b674005c to your computer and use it in GitHub Desktop.
Save mweststrate/d3d6ab3333b886faed6d4f29b674005c to your computer and use it in GitHub Desktop.
(TypeScript) typeswitcher, like switch, but with constructor based cases and expressions with inferred types
/**
* Usage:
typeSwitch(someInstance, defaultvalue)
.when(MyClass, i => result)
.when(OtherClass, i => otherResult)
.get()
In the expressions, the type of the 'i' param should be inferred correctly, see the attribute default value checks
*/
export function typeSwitch<T, R>(instance: T, defaultValue?: R): TypeSwitcher<T, R> {
return new TypeSwitcher<T, R>(instance, defaultValue);
}
interface ITypeSwitchEntry<T, R> {
type: new (...args: any[]) => T;
expr: (instance: T) => R;
}
interface IConstructor<T> {
new (...args): T;
}
class TypeSwitcher<T, R> {
private cases: ITypeSwitchEntry<T, R>[] = [];
constructor(private instance: T, private _defaultValue?: R) { }
when<Z extends T>(clazz: IConstructor<Z>, expr: (instance: Z) => R): TypeSwitcher<T, R> {
this.cases.push({ type: clazz, expr: expr });
return this;
}
get(): R {
for (var i = 0, l = this.cases.length; i < l; i++)
if (this.instance instanceof this.cases[i].type)
return this.cases[i].expr(this.instance);
if (this._defaultValue !== undefined)
return this._defaultValue;
throw new Error("Unsupported type: " + this.instance);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment