Skip to content

Instantly share code, notes, and snippets.

@artalar
Last active March 28, 2019 11:14
Show Gist options
  • Select an option

  • Save artalar/7eaef85279f26a71e93e3f0586832c82 to your computer and use it in GitHub Desktop.

Select an option

Save artalar/7eaef85279f26a71e93e3f0586832c82 to your computer and use it in GitHub Desktop.
// @flow
function match<I: [*] | [*, *], O>(
cb: (test: (predicate?: (...a: I) => any) => string) => { [string]: O | ((...a: I) => O) }
): (...a: I) => ?O {
const predicates = {};
function test(predicate: (...a: I) => any = () => true): string {
const predicateName = Math.random().toFixed(5);
predicates[predicateName] = predicate;
return predicateName;
}
const tests: { [string]: O | ((...a: I) => O) } = cb(test);
return function(...a: I): ?O {
for (const predicateName in predicates) {
if (predicates[predicateName](...a)) {
const handler = tests[predicateName];
return typeof handler === 'function' ? handler(...a) : handler;
}
}
};
}
const matcher = match<[string, string], string>(test => ({
[test(name => !name)]: 'User',
[test(name => name.length < 10)]: (firstName, lastName) => `${firstName} ${lastName}`,
[test(name => name.length >= 10)]: firstName => firstName,
[test()]: () => {
throw new Error('Unexpected case');
},
[test(number => number.toFixed())]: () => 123,
}));
const result = matcher('a', 'b');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment