Last active
October 4, 2018 19:08
-
-
Save SlimTim10/f2adbb7310278d493a9fedb039b9e9fd to your computer and use it in GitHub Desktop.
Poor man's type checking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ts = require('./type-signatures') | |
// Without using module | |
// number -> string -> number | |
const addNums_ = (n, str) => n + parseInt(str) | |
// With using module | |
const addNums = ts('number', 'string')( | |
(n, str) => n + parseInt(str) | |
) | |
// Works because the types match | |
// console.log(addNums(2, '3')) | |
// Produces a type error | |
// console.log(addNums('2', '3')) | |
// Supports currying | |
const add = ts('number')( | |
x => ts('number')( | |
y => x + y | |
) | |
) | |
// console.log(add(2)(3)) | |
const add3 = add(3) | |
// console.log(add3('5')) | |
function test() { | |
addNums('2', '3') | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Object.defineProperty(global, '__stack', { | |
get: function() { | |
const orig = Error.prepareStackTrace | |
Error.prepareStackTrace = (_, stack) => stack | |
const err = new Error | |
Error.captureStackTrace(err, arguments.callee) | |
const stack = err.stack | |
Error.prepareStackTrace = orig | |
return stack | |
} | |
}) | |
const ts = (...types) => f => (...args) => { | |
if (types.length !== args.length) { | |
const err = new TypeError('Number of arguments does not match type signature') | |
return console.error(err.stack) | |
} | |
const errs = args | |
.map((arg, i) => { | |
const type = types[i] | |
if (typeof arg !== type) { | |
const fileName = __stack[3].getFileName() | |
const lineNumber = __stack[3].getLineNumber() | |
const columnNumber = __stack[3].getColumnNumber() | |
const err = new TypeError(`Couldn't match expected type '${type}' with actual type '${typeof arg}'`) | |
console.error(`at ${fileName}:${lineNumber}:${columnNumber}`) | |
return err | |
} else { | |
return null | |
} | |
}) | |
.filter(Boolean) | |
if (errs.length > 0) { | |
return errs.forEach(err => console.error(err.stack)) | |
} | |
return f(...args) | |
} | |
module.exports = ts |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment