JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://jsm.io/jsm.js"></script>

JavaScript

/*jshint asi: true undef: true es5: true node: true devel: true
         forin: false */
/*global define: true document: true */
define("demo", function() {

var guards = require('https://raw.github.com/Gozala/guards/v0.3.0/guards.js')

// Define a { x, y } data structure, where x and y fallback to 0.
var Point = guards.Schema({
    x: guards.Number(0),
    y: guards.Number(0)
})

execute(function() {
  return Point({ x: 17 })
})
//> { x: 17, y: 0 }

// Define any type of guard as a function
function color(value) {
  // If validates just return value
  if (typeof value === "number" && value <= 255 && value >= 0) return value
  // If not throw TypeError
  throw new TypeError("Color is a number between 0 and 255")
}

// Define a [0-255, 0-255, 0-255] data structure guard.
var RGB = guards.Tuple([ color, color, color ])

execute(function() {
  return RGB([ 15, 3, 200 ])
})

//> [ 15, 3, 200 ]
execute(function() {
  return RGB([ 1, 2, 3, 4 ])
})
//> [ 1, 2, 3 ]

execute(function() {
  return RGB([ 1, 2, {}])
})
//> TypeError: Color is a number between 0 and 255


// Compose data structure out of existing guards.
var Segment = guards.Schema({
  start: Point,
  end: Point,
  color: RGB,
})

execute(function() {
  return Segment({ end: { y: 23 }, color: [17, 255, 0] })
})
//> { start: { x: 0, y: 0 }, end: { x: 0, y: 23 }, color: [ 17, 255, 0 ] }

execute(function() {
  return Segment({ start: 0, end: { y: 23 }, color: [17, 255, 0] })
})
//> TypeError: Object expected instead of number `0`

execute(function() {
  return Segment({ color: [ 10, 40, '30' ]})
})
//> TypeError: Color is a number between 0 and 255


})
require.main('demo')

function execute(task) {
  try {
    document.body.innerHTML += '<pre>&gt; ' + JSON.stringify(task()) + '</pre>'
  } catch (error) {
    document.body.innerHTML += '<pre style="color:red">&gt; ' + error.message + '</pre>'
  }
}