Mezzanine
Fantasy land union types with pattern matching
Installation
$ npm install --save mezzanine
Motivation
Principles:
- No
this
- No
new
- No
.prototype
- Minimal api surface
Object classes, described with rules and linked methods.
Usage
const Point = Type`Point` x: Number y: Number const Shape = Union`Shape` Line: start: Point end : Point Circle: center: Point radius: Number const point1 = Point x: 1 y: 2 const point2 = Point x: 0 y: 10 point1 // => truepoint1 // => true, smart type inference const shape1 = shape1type // => Line
syntaxShockMode = off
You can also use the library without backtick tags, with classic parentheses.
const Point = x: Number y: Number
Methods & computed properties
Second argument in the constructor is the function map, object with linked methods, which apply and attach to instances on create
const Point = Type`Point` x: Number y: Number concat: // context, works as `this` // can be another Point instance or plain object Point x: ctxx + pointx y: ctxy + pointy const Rectangle = Type`Rectangle` root : Point width : Number height: Number ctxwidth * ctxheight //Will be computed property { return ctxroot } const rect = /* => { type : 'Rectangle', root : { type: 'Point', x: 1, y: 4 }, width : 10, height : 5, area : 50, endPoint: { type: 'Point', x: 11, y: 9 } }*/
Iterable types
You can define iterable types with Symbol.iterator
. Another symbols, well-known or not, are also available as method names
const Iterable = Type`Iterable`Array valuelength { return { const length = ctxlength for let i = 0; i < length; i++ ctxvaluei } }const result = ...// => ['a', 'b', 'c']
Data types
Mezzanine has some built-in object classes.
Tuple
const Point = Type`Point` x: Number y: Number const NamedPoint = const point1 = const point2 = NamedPoint // => true
Tuples are iterable
point2length// => 2for const value of point2 console// => 'end point'// => { type: 'Point', x: 2, y: 3 }
Maybe
const filterFarmer = humanoccupation === 'farmer' const users = 230: name: 'bob' occupation: 'farmer' 231: name: 'jerry' occupation: 'doctor' 232: name: 'frank' occupation: 'teacher' const readField = dataprop const toUpperCase = text const maybeName = // => BOB
What happens if we select an id that doesn't exist? Nothing. The whole chain will safely skip incorrect values without changes
Ramda support
const readName = users // => { type: 'Just', value: 'BOB' }users // => { type: 'Nothing', value: undefined }users // => { type: 'Nothing', value: undefined }
Recipes
Any
type
const Any = Type`Any`T
or
const Any = Type`Any` true
Usage:
const example1 = const example2 = const example3 =
License
The project is released under the Mit License