minimal composable type abstraction
npm install --save mintype
for a better type library, see tcomb
.
what's a type?
a Type T
is a function where
given a value v
, T
returns either:
- a new value
v*
(which might be===
tov
) - an instance of
TypeError
and given v*
, T
returns v*
.
we can use this in many interesting ways
- create a factory
Function
that is idempotent, as inF(value) === F(F(value))
- to do this, we throw errors in development, and ignore them in production.
- create a validation
Function
that returnsTypeError
ornull
- create a test
Function
that returnsBoolean
- compose many types together into one type
const ty = require('mintype')
const Vector = ty.compose(
ty.Array,
(vector) => vector.length === 2
? vector : new TypeError('Vector must be array of [x, y].')
,
(vector) => {
for (var i = 0; i < vector.length; i++) {
const result = ty.validate(ty.Number, vector[i])
if (result instanceof TypeError) return result
}
return vector
}
)
const Location = ty.struct('Location', {
position: Vector,
velocity: Vector
})
const location = ty.create(Location, {
position: [100, 0],
velocity: [0, 1]
})
console.log('location', location)
// location Struct {
// type: 'Location',
// position: [ 100, 0 ],
// velocity: [ 0, 1 ] }
the top-level mintype
module is a grab bag of all mintype/*
modules.
you can also require each module separately like require('mintype/create')
.
create(T, value)
only returns the typed version of value
, as in:
- if there is an error from applying the type
T
, thencreate
will throw - otherwise
create
returns the resulting value from applying the typeT
if value
is type T
, return null
;
else return TypeError
returned from T(value)
.
if value
is type T
, return true
;
else return false
.
ty.String
: stringsty.Number
: numbersty.Integer
: integersty.Boolean
: booleansty.Array
: arraysty.Object
: plain objectsty.Function
: functionsty.RegExp
: regular expressionsty.Date
: datesty.Nil
:null
orundefined
ty.Any
: any value
given a String
(or Symbol
) name
and an Object
of property types corresponding to property names,
returns a Type
that uses a constructor function for efficient data structures.
calling Type(props)
either returns:
- the first error encountered in evaluating the props
- a
new
instance of the struct's evaluated props called on the constructor function.
note: it's possible to define methods on Type.prototype
, which will show up as methods on any returned instances.
compose many types into one type, as so:
const Integer = compose(
ty.Number,
(value) => value % 1 === 0
? value
: new TypeError(`expected ${value} % 1 === 0`)
)
returns a type that can either be of type ty.Nil
or the type passed to ty.maybe
for more performant types in production, only do expensive error-checking if process.env.NODE_ENV !== 'production'
.
this allows the code to be stripped out with browserify
bundles using envify
and uglifyify
.
the built-in types and type utilities do this already, but if you are supplying your own types from scratch you will need to do this on your own.
i built this to replace tcomb
within inu-plays-rougelike
due to performance problems (and fun ideas), the integration is still a work in progress.
tcomb
- @dominictarr's idea of validation as a reducer function (initialState, value) -> (nextState | false)
stampit
- json-schema type objects
- C data types
The Apache License
Copyright © 2016 Michael Williams
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.