takor
TypeScript icon, indicating that this package has built-in type declarations

1.0.1 • Public • Published

Flexible and composable runtime type assertion for Javascript. Syntax inspired by prop-types. Supports:

  • ES6 data structures
  • inner elements in data structures
  • nested assertions
  • inverse assertions
  • custom validators

Quick Examples

// takor.oneOf
const isNumOrStr = takor.oneOf(Number, String)
isNumOrStr(10) // true
isNumOrStr(new Set) // false
 
// takor.shape basic
const checkShape = takor.shape({
    key1: takor.oneOf(Number, String)
})
checkShape({ // true
    key1: 'string'
})
 
// takor.shape with nested assertions
const checkNestedElement = takor.shape({
    key1: takor.shape({
        key2: takor.arrayOf(Number, Set, String)
    })
})
checkNestedElement({ // true
    key1: {
        key2: [0, new Set, '']
    }
})
 
checkNestedElement({ // false
    key2: {
        key1: [0, new Set, '']
    }
})
 
// supports literal number or string
const isValidDogBreed = takor.oneOf('terrier', 'greyhound', 'golden retriever')
isValidDogBreed('terrier') // true
isValidDogBreed('persian') // false
 
// custom validator(s)
const lessThanTen = (el) => el < 10
const greaterThanThree = (el) => el > 3
const goodNumberRange = takor.allOf(lessThanTen, greaterThanThree)
// compose existing validator into another
const validNumRangeOrStr = takor.arrayOf(goodNumberRange, String)
 
validNumRangeOrStr([8, 4, 3.5, 5]) // true
validNumRangeOrStr([8, 4, '100', 5]) // true
validNumRangeOrStr([8, 4, 100, 5]) // false
validNumRangeOrStr(10) // false 
validNumRangeOrStr(new Map) // false
 
// takor.mapOf
const validMap = takor.mapOf(
    [Number, takor.oneOf(Array, Set)],
    [String, String]
)
validMap(new Map([ // true
    [10, []],
    [10, new Set],
    ['10', '10']
]))
 
validMap(new Map([ // false
    [10, []],
    [10, new Set],
    ['10', new Set]
]))
 
// takor.not
const nonNullOrArray = takor.not.oneOf(null, Array)
nonNullOrArray(10) // true
nonNullOrArray([]) // false
 
 
/**
 * Practical example:
 * Checks if the api response has a data key that is an array of objects
 * that have the keys id, phoneNumber, and name, where
 * the phone number is also checked if it is a valid phone number
 */
const isValidPhoneNumber = (phoneNumber) => {
    return /^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$/.test(phoneNumber)
}
const isExpectedApiResponse = takor.shape({
    status: Number,
    message: String,
    data: takor.arrayOf(takor.shape({
        id: Number,
        phoneNumber: isValidPhoneNumber,
        name: String,
    })),
})

Table of Contents

static method type description
allOf ListOfMatchers Passed in validators must meet every criteria
arrayOf ListOfMatchers Asserts the element is an array with specific types stated
is SingleMatcher Performs an assertion on a single value
mapOf ListOfTupleMatchers Asserts inner elemnts of an es6 Map
oneOf ListOfMatchers At least one validator must match
setOf ListOfMatchers Asserts inner elements of a Set
shape ShapeOfMatchers Asserts a specific structure of a pojo (plain old javascript object)
not.arrayOf ListOfMatchers The converse arrayOf
not.is SingleMatcher The converse is
not.mapOf ListOfTupleMatchers The converse mapOf
not.oneOf ListOfMatchers The converse oneOf
not.setOf ListOfMatchers The converse setOf
not.shape ShapeOfMatchers The converse shape

Available Matchers

Description

Out-of-the-box type validators. See examples for usage.

  • Number (Constructor)
  • String (Constructor)
  • Set (Constructor)
  • Map (Constructor)
  • Boolean (Constructor)
  • Array (Constructor)
  • Function (Constructor)
  • null
  • undefined
  • NaN
  • true
  • false

any

type: IAny

Desc

Not a validator. A function that is true for any value

Notes

Intended use is as an argument for validators.

Examples
takor.any(10) // true
 
const assertKeysOnly = takor.shape({
    data: takor.shape({
        entry: takor.any
    })
})
 
assertKeysOnly({ // true
    data: {
        entry: []
    }
})

falsey

type: IFalsey

Desc

Not a validator. It is a raw function that checks for any falsey value type

Notes

More information on falsey can be found on MDN Intended use is as an argument for validators.

Examples
takor.falsey(false) // true
takor.falsey([]) // false
 
const falseyOnly = takor.arrayOf(takor.falsey)
falseyOnly([1, null, '']) //  false
falseyOnly([null, 0, '']) //  true

pojo

type: IPojo

Desc

Not a validator. It is a raw function that if a value is a pojo. Use shape to specify a pojo shape

Notes

Intended use is as an argument for validators

Examples
takor.pojo({}) // true
takor.pojo(10) // false
 
// any object or array as long as top level key is `data`
const isPayload = takor.shape({
    data: takor.oneOf(takor.pojo, Array)
})
 
isPayload({ // false
    result: {}
})
 
isPayload({ // true
    data: {}
})
 
isPayload({ // true
    data: []
})
 

truthy

type: ITruthy

Desc

Not a validator. It is a function that checks if the value is truthy.

Notes

More information on truthy can be found on MDN Intended use is as an argument for validators.

Examples
takor.truthy(10) // true
takor.truthy(NaN) // false
 
const truthiesOnly = takor.arrayOf(takor.truthy)
truthiesOnly([1, new Set, '1']) //  true
truthiesOnly([1, new Set, '']) //  false

allOf

type: ListOfMatchers

Desc

Passed in validators must meet every criteria

Notes
  • Contradictory validators will result in false
Examples
const isPopulated = (arr) => arr.length > 0
const populatedStringArr = takor.allOf(takor.arrayOf(String), isPopulated)
populatedStringArr(['']) // true
populatedStringArr([]) // false
populatedStringArr([10]) // false
 
// contradictory types. impossible to meet criteria
const impossibleCheck = takor.allOf(Number, String)
impossibleCheck(10) // false
impossibleCheck('') // false

arrayOf

type: ListOfMatchers

Desc

Asserts the element is an array with specific types stated

Notes
Examples
const assert = takor.arrayOf(Number)
assert(['Number']) //false
 
 
const checkInnerOobj = takor.arrayOf(
    takor.shape({
        hi: Number
    }),
)
checkInnerOobj([{ hi: 10 }]) // true
 
 
const goodShapeNumOrStr = takor.arrayOf(
    takor.shape({
        hi: Number
    }),
    String,
    Number,
)
goodShapeNumOrStr([10, { hi: 10 }, new Map]) // false
 
const emptyArr = takor.arrayOf()
emptyArr([]) // true
emptyArr([1]) // false

is

type: SingleMatcher

Desc

Performs an assertion on a single value

Notes

This is a less flexible version of typeof. takor.is only accepts a single validator, while typeof accepts an arbitrary number.

Examples
const isStr = takor.is(String)
isStr('') // true
isStr(10) // false
 
 
// custom validator
takor.is((el) => el > 0)
enforcer(190) // true
enforcer(-1) // false

mapOf

type: ListOfTupleMatchers

Desc

Asserts inner elemnts of an es6 Map

Notes

mapOf takes an arbitrary number of tuples, correlating to [key, value] assertions

Examples
const allNumbers = takor.mapOf(
    [Number, Number]
)
allNumbers(new Map([ // true
    [10, 10]
]))
allNumbers(new Map([ // false
    [10, '10']
]))
 
 
// inner assertion inside mapOf
const valueMapShape = takor.shape({
    key: takor.shape({
        key2: takor.oneOf(null, Number)
    })
})
const checkMapValue = takor.mapOf(
    [String, assertShape]
)
checkMapValue(new Map([ // true
    ['12', { key: { key2: null } }],
])))
 

not.arrayOf

type: ListOfMatchers

Desc

The converse arrayOf

Notes

Any non-Array value will be true

Examples
const checkArray = takor.not.arrayOf(Array, String, Set)
checkArray([[]]) // false
checkArray([10]) // true
checkArray(NaN) // true

not.is

type: SingleMatcher

Desc

The converse is

Notes
Examples
const checkStrLen = takor.not.is((str) => str.length === 0)
checkStrLen('') // false
checkStrLen('10') // true

not.mapOf

type: ListOfTupleMatchers

Desc

The converse mapOf

Notes

non-Map values will always be true

Examples
const notAllNumbers = takor.not.mapOf(
    [Number, Number]
)
 
notAllNumbers(new Map([ // false
    [10, 10]
]))
notAllNumbers(new Map([ // true
    [10, '10']
]))

not.oneOf

type: ListOfMatchers

Desc

The converse oneOf

Notes
Examples
const keyIsNotNull = takor.shape({
    key: takor.not.oneOf(null)
})
 
keyIsNotNull(({ // true
    key: 10
}))

not.setOf

type: ListOfMatchers

Desc

The converse setOf

Notes
Examples
const notStrs = takor.not.setOf(String)
notStrs(new Set([10])) // true
notStrs(new Set([10, '12'])) // false

not.shape

type: ShapeOfMatchers

Desc

The converse shape

Notes
Examples
const notEmpty = takor.not.shape({})
notEmpty({ a: 10 }) // true
notEmpty({}) // false

oneOf

type: ListOfMatchers

Desc

At least one validator must match

Notes
Examples
const numOrStr = takor.oneOf(String, Number)
numOrStr(10) // true
numOrStr(new Set) // false
 
// check inner elements of an array
const dogOrCat = takor.oneOf('dog', 'cat')
dogOrCat('cat') // true
dogOrCat('bird') // false

setOf

type: ListOfMatchers

Desc

Asserts inner elements of a Set

Notes
Examples
const allNums = takor.setOf(Number)
setOfNums(new Set([10, 30, 40])) // true
 
const strOrNums = takor.setOf(String, Number)
strOrNums(new Set([10, '12'])) // true
strOrNums(new Set([10, '12', new Map])) // false

shape

type: ShapeOfMatchers

Desc

Asserts a specific structure of a pojo (plain old javascript object)

Notes
  • shape checks only top level keys.
  • Nest another shape to assert deeper
  • Does not check for superfluous keys. Only ensures types of defined keys
Examples
const assert = takor.shape({
    key: String
})
assert({key: ''}) // true
 
 
const assertNested = takor.shape({
    key: takor.shape({
        key: takor.shape({
            key1: String
        })
    })
})
 
assertNested({ // false
    key: {
        els: '10'
    }
})
 
const assertApiPayload = takor.shape({
    data: takor.arrayOf(takor.shape({
        user: takor.shape({
            phoneNumber: Number,
            firstName: String
        })
    }))
})
 
assertApiPayload({ // true
    data: [{
        user: {
            phoneNumber: 4024224856,
            firstName: 'john',
            lastName: 'smith' // does not check this key
        }
    }]
})

types

// Custom validators are any function that accepts an input value and returns a boolean
type ICustomValidator = (el: any) => boolean
 
// Baked in common matchers, so you don't have to constantly write them yourself
type IPojo = (el: any) => boolean
type IAny = (el: any) => boolean
type ITruthy = (el: any) => boolean
type IFalsey = (el: any) => boolean
 
// Shape accepts an object where the value is a validator or a primitive literal
type ShapeOfMatchers = {
    [key: string]: IMatcher
}
 
// A function that takes an arbitrary number of matchers that returns another function to assert values
type ListOfMatchers = (...matchers: IMatcher[]) => (el: any) => boolean
 
// A function that takes an arbitrary number of tuple of matchers that return another function to assert values
type ListOfTupleMatchers = (...matchers: [IMatcher, IMatcher][]) => (el: any) => boolean
 
// Only accepts a single matcher
type SingleMatcher = (matcher: IMatcher) => (el: any) => boolean
 
// List of valid matchers
type IMatcher = 
    SetConstructor |
    MapConstructor |
    NumberConstructor |
    StringConstructor |
    null |
    undefined |
    ArrayConstructor |
    BooleanConstructor |
    true |
    false |
    string |
    number |
    ICustomValidator | // custom validator
    IPojo | // built in matcher
    IAny | // built in matcher
    ITruthy | // built in matcher
    IFalsey // built in matcher
 

Package Sidebar

Install

npm i takor

Weekly Downloads

2

Version

1.0.1

License

MIT

Unpacked Size

42.1 kB

Total Files

14

Last publish

Collaborators

  • andrew1007