xmatch
Simple pattern matching for ES6 (no transpilation!)
Property matching
const { match } = require('xmatch');
match(obj, [
({ x }) => console.log('x', x),
({ y }) => console.log('y', y),
({ z }) => console.log('z', z),
// Exhaustive match; will throw `xmatch.UnmatchedPatternError` unless uncommented:
// other => console.error('Something else', other),
]);
Iterable matching
const { match } = require('xmatch');
match(arr, [
([]) => 'empty',
([x]) => `x=${x}`,
([x, y]) => `x=${x},y=${y}`,
([x, y, ...{ length }]) => `x=${x},y=${y},rest.length=${length}`,
]);
Custom guards
const { match, guard } = require('xmatch');
match(obj, [
({ command }) => {
// When you want to match simple values:
guard(command === 'ignore');
/* Do nothing */
},
({ command }) => {
// Or, say, match result of regex:
let [, name, args] = guard(command.match(/^(\w+):(.*)$/));
console.log({ name, args });
},
({ command }) => {
throw new Error(`Invalid command: ${command}`);
},
]);
Shape assertions
const { guard } = require('xmatch');
const { x, y } = guard({ x: 1, y: 2 }); // OK
const { x, y } = guard({ x: 1, z: 2 }); // throws `xmatch.UnmatchedPatternError`
Known issues
- You can't use literals directly in patterns (this is limitation of ES6 syntax, can be fixed as part of https://github.com/tc39/proposal-pattern-matching).
- You can't use default values for parameters. This is limitation of the way matching is implemented, and you'll have to resolve defaults yourself if that's what you want.
- Trying to further destructure or access undefined properties of an object will also trigger the match guard (#1). This is tricky to workaround without changing the syntax, but I'll look into it (and happy to hear any suggestions).
- This uses dynamic metaprogramming via
Proxy
which might have undesirable performance effect on hot code paths. If your benchmarks suggest it's causing critical performance issues, consider using transpiler plugins instead. Proxy
is not implemented in pre-ES6 browsers and can't be polyfilled, so use this only if you're okay with the supported target set: https://caniuse.com/#feat=proxy