Skip to content

Instantly share code, notes, and snippets.

@anddoutoi
Last active February 9, 2017 12:31
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 anddoutoi/11ea8d9a7faec4a8e89ef60054e9474d to your computer and use it in GitHub Desktop.
Save anddoutoi/11ea8d9a7faec4a8e89ef60054e9474d to your computer and use it in GitHub Desktop.
I, for one, welcome our new overloards…

Overloard

Utility function to create overloaded functions

  • Start in usage.js and follow the imports
  • Userland interesting stuff can be found in factories.js
  • usage.js for examples of… usages
import overload from './overload';
import User from './user';
const createUser = overload({
'array': (master) => ([firstName, lastName]) => master({firstName, lastName}),
'object': () => (userProperties) => new User(userProperties),
'string, string': (master) => (firstName, lastName) => master({firstName, lastName}),
});
export {
createUser,
};
/*
- Takes implementations as an object, each key/value is an implementation
- An implementation is:
key = signature as string
value = implementation as hoc function that provides a proxy function (called "master" in this example)
*/
import typeIs from './type-is';
export default overload;
function overload(implementations) {
const cache = {};
Object.keys(implementations).forEach((signature) => {
cache[signature.replace(/ /g, '')] = implementations[signature];
});
return function master(...args) {
const signature = args.map((arg) => typeIs(arg)).join(',');
const implementation = cache[signature];
if (typeof implementation !== 'function') {
throw new TypeError(`No such signature: ${signature}`);
}
return implementation(master).apply(this, args);
};
}
// A better typeof
export default typeIs;
function typeIs(value) {
if (Array.isArray(value)) {
return 'array';
}
if (value === null) {
return 'null';
}
const type = typeof value;
return type === 'object' ? getObjectType(value) || type : type;
}
const internalClassToTypeMap = {
'[object Boolean]': typeof true,
'[object Date]': 'date',
'[object Number]': typeof 0,
'[object String]': typeof '',
// add more at your discretion
};
function getObjectType(value) {
const internalClass = Object.prototype.toString.call(value);
return internalClassToTypeMap[internalClass];
}
import {createUser} from './factories';
const jane = createUser({
firstName: 'Jane',
lastName: 'Doe',
});
const john = createUser('John', 'Doe');
const anotherJohn = createUser(['John', 'Doe']);
export default User;
function User({firstName, lastName}) {
this.firstName = firstName;
this.lastName = lastName;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment