JSPM

  • Created
  • Published
  • Downloads 398
  • Score
    100M100P100Q98339F
  • License MIT

Babel plugin for runtime type checking using tcomb

Package Exports

  • babel-plugin-tcomb

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (babel-plugin-tcomb) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

tcomb is a library for Node.js and the browser which allows you to check the types of JavaScript values at runtime with a simple and concise syntax. It's great for Domain Driven Design and for adding safety to your internal code.

babel-plugin-tcomb is a babel plugin for runtime type checking using tcomb. You can annotate a function (arguments and return type) with tcomb types.

How it works

import t from 'tcomb';

// add type annotations
function foo(x: t.Number, y: t.String): t.String {
  return x + y;
}

// compiled to
function foo(x: t.Number, y: t.String): t.String {

  // check the arguments: tcomb types are identity functions
  // containing type asserts
  x = t.Number(x);
  y = t.String(y);

  // exec the original function
  const ret = function (x, y) {
    return x + y;
  }(x, y);

  // check the return type
  return t.String(ret);
}

Now the foo function is type-checked, this means...

foo(1, 'a'); // => ok
foo(1, 2); // => ...will throws "[tcomb] Invalid value 2 supplied to String"

Caveats

  • Destructuring and typed default values are not (yet) supported

Setup

First, install via npm.

npm install --save-dev babel-plugin-tcomb

Then, in your babel configuration (usually in your .babelrc file), add "tcomb" to your list of plugins:

{
  "plugins": ["tcomb"]
}

or

"env": {
  "development": {
    "plugins": [
      "tcomb"
    ]
  }
}

Webpack config

module: {
  loaders: [
    {
      test: /\.jsx?$/,
      loader: 'babel?plugins=babel-plugin-tcomb'
    }
  ]
}

Features

struct combinator

const Person = t.struct({
  name: t.String
});

function foo(person: Person) {
  return person.name;
}

// compiles to
function foo(person: Person) {
  person = Person(person);

  return person.name;
}

refinement combinator

const Integer = t.refinement(t.Number, (n) => n % 1 === 0);

function foo(x: Integer) {
  return x;
}

// compiles to
function foo(x: Integer) {
  x = Integer(x);

  return x;
}

maybe combinator

function foo(x: ?t.String) {
  return x;
}

// compiles to
function foo(x: ?t.String) {
  x = t.maybe(t.String)(x);

  return x;
}

list combinator

function foo(x: Array<t.String>) {
  return x;
}

// compiles to
function foo(x: Array<t.String>) {
  x = t.list(t.String)(x);

  return x;
}

tuple combinator

function foo(x: [t.String, t.Number]) {
  return x;
}

// compiles to
function foo(x: [t.String, t.Number]) {
  x = t.tuple([t.String, t.Number])(x);

  return x;
}

union combinator

function foo(x: t.String | t.Number) {
  return x;
}

// compiles to
function foo(x: t.String | t.Number) {
  x = t.union([t.String, t.Number])(x);

  return x;
}

dict combinator

function foo(x: {[key: t.String]: t.Number}) {
  return x;
}

// compiles to
function foo(x: { [key: t.String]: t.Number }) {
  x = t.dict(t.String, t.Number)(x);

  return x;
}

intersection combinator

function foo(x: t.Number & t.String) {
  return x;
}

// compiles to
function foo(x: t.Number & t.String) {
  x = t.intersection([t.Number, t.String])(x);

  return x;
}

Arrow functions

const f = (x: t.String) => x;

// compiles to
const f = x => {
  x = t.String(x);
  return x;
};

Classes

class A {
  foo(x: t.String): t.String {
    return x;
  }
}

// compiles to
class A {
  foo(x: t.String): t.String {
    x = t.String(x);

    const ret = function (x) {
      return x;
    }(x);

    return t.String(ret);
  }
}