Last active
October 13, 2015 20:48
-
-
Save frostney/4254184 to your computer and use it in GitHub Desktop.
Chainable type checks in CoffeeScript (Method chaining with type checks)
Also allows to wrap type checks into an object, which is a safer option than a switch-case-typeof check
AMD definition included :)
This file contains 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
do (root = exports ? this) -> | |
'use strict' | |
root.check = (variable, checkObject) -> | |
stringedVar = {}.toString.call variable | |
typeName = stringedVar.slice(8, stringedVar.length - 1).toLowerCase() | |
checkType = (typeString, cb, inverse) -> | |
if inverse | |
cb?(variable) unless typeName is typeString | |
else | |
cb?(variable) if typeName is typeString | |
### | |
Else is a reserved keyword, while CoffeeScript interpolates it correctly, | |
it can only be written as check(...).['else']... | |
check(...).otherwise(...) is a better choice if using plain JavaScript | |
### | |
unless checkObject | |
result.else = result.otherwise = (cb) -> checkType typeString, cb, !inverse | |
result | |
types = (inverse) -> | |
valid: (cb) -> | |
if inverse | |
cb(variable) unless variable? | |
else | |
cb(variable) if variable? | |
@ | |
undefined: (cb) -> checkType "undefined", cb, inverse | |
null: (cb) -> checkType "null", cb, inverse | |
string: (cb) -> checkType "string", cb, inverse | |
number: (cb) -> checkType "number", cb, inverse | |
object: (cb) -> checkType "object", cb, inverse | |
array: (cb) -> checkType "array", cb, inverse | |
function: (cb) -> checkType "function", cb, inverse | |
if checkObject | |
typeFuncs = types(false) | |
for key, value of checkObject | |
if key.indexOf(',') > -1 | |
keyArray = key.split ',' | |
typeFuncs[k.trim()](value) for k in keyArray | |
else | |
typeFuncs[key] value | |
result = undefined | |
else | |
result = types(false) | |
result.not = types(true) | |
result | |
# AMDs are awesome :) | |
root.define?('check', [], -> root.check) unless exports? |
This file contains 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
check('test') | |
.not.string(-> console.log 'not a string') | |
.else(-> console.log 'Logically, should be a string') | |
.number((v) -> console.log("its a number with value: #{v}")) | |
check({}) | |
.object(-> console.log 'Is an object') | |
.else(-> console.log 'Not an object') | |
.else(-> console.log 'Maybe an object') | |
# Instead of using method chaing, you can also use | |
# a plain object with the type as the key and the value is the callback function | |
check {}, | |
object: -> console.log 'Is an object' | |
number: -> console.log 'Is a number' | |
check 8, | |
object: -> console.log 'Is an object' | |
number: -> console.log 'Is a number' | |
# Multiple keys seperated by a comma also work, just make sure the key is | |
# written as a key | |
check 'test', | |
'string, number': -> console.log 'Either string or number' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment