Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

tcomb

gcanti6.7mMIT3.2.29TypeScript support: included

Type checking and DDD for JavaScript

type, combinators, checking, safety, model, domain, debugging, immutable, DDD, JSON, store

readme

build status dependency status npm downloads

"Si vis pacem, para bellum" - (Vegetius 5th century)

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.

TypeScript / Flowtype users

You may want to check out io-ts

IMPORTANT: Running in production

tcomb is supposed to be used in development and is disabled in production. If you want type checks in production you may use

Setup

npm install tcomb --save

Code example

A type-checked function:

import t from 'tcomb';

function sum(a, b) {
  t.Number(a);
  t.Number(b);
  return a + b;
}

sum(1, 's'); // throws '[tcomb] Invalid value "s" supplied to Number'

// using babel-plugin-tcomb
function sum(a: number, b: number) {
  return a + b;
}

A user defined type:

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

A type-checked class:

const Person = t.struct({
  name: t.String,              // required string
  surname: t.maybe(t.String),  // optional string
  age: t.Integer,                // required integer
  tags: t.list(t.String)       // a list of strings
}, 'Person');

// methods are defined as usual
Person.prototype.getFullName = function () {
  return `${this.name} ${this.surname}`;
};

const person = Person({
  surname: 'Canti'
}); // throws '[tcomb] Invalid value undefined supplied to Person/name: String'

Chrome DevTools:

throws

Docs

Features

Lightweight

3KB gzipped, no dependencies.

Type safety

All models defined with tcomb are type-checked.

Note. Instances are not boxed, this means that tcomb works great with lodash, Ramda, etc. And you can of course use them as props to React components.

Based on set theory

Domain Driven Design

Write complex domain models in a breeze and with a small code footprint. Supported types / combinators:

  • user defined types
  • structs
  • lists
  • enums
  • refinements
  • unions
  • intersections
  • the option type
  • tuples
  • dictionaries
  • functions
  • recursive and mutually recursive types
  • interfaces

Immutability and immutability helpers

Instances are immutable using Object.freeze. This means you can use standard JavaScript objects and arrays. You don't have to change how you normally code. You can update an immutable instance with the provided update(instance, spec) function:

const person2 = Person.update(person, {
  name: { $set: 'Guido' }
});

where spec is an object containing commands. The following commands are compatible with the Facebook Immutability Helpers:

  • $push
  • $unshift
  • $splice
  • $set
  • $apply
  • $merge

See Updating immutable instances for details.

Speed

Object.freeze calls and asserts are executed only in development and stripped out in production (using process.env.NODE_ENV !== 'production' tests).

Runtime type introspection

All models are inspectable at runtime. You can read and reuse the information stored in your types (in the meta static member). See The meta object in the docs for details.

Libraries exploiting tcomb's RTI:

Easy JSON serialization / deserialization

Encodes / decodes your domain models to / from JSON for free.

Debugging with Chrome DevTools

You can customize the behavior when an assert fails leveraging the power of Chrome DevTools.

// use the default...
t.fail = function fail(message) {
  throw new TypeError('[tcomb] ' + message); // set "Pause on exceptions" on the "Sources" panel for a great DX
};

// .. or define your own behavior
t.fail = function fail(message) {
  console.error(message);
};

Pattern matching

const result = t.match(1,
  t.String, () => 'a string',
  t.Number, () => 'a number'
);

console.log(result); // => 'a number'

Babel plugin

Using babel-plugin-tcomb you can also write (Flow compatible) type annotations:

function sum(a: number, b: number): number {
  return a + b;
}

TypeScript definition file

index.d.ts

Contributors

How to Build a standalone bundle

git clone git@github.com:gcanti/tcomb.git
cd tcomb
npm install
npm run dist

Will output 2 files:

  • dist/tcomb.js (development)
  • dist/tcomb.min.js (production) Object.freeze calls and asserts stripped out

Related libraries

Similar projects

License

The MIT License (MIT)

changelog

Changelog

Tags:

  • [New Feature]
  • [Bug Fix]
  • [Breaking Change]
  • [Documentation]
  • [Internal]
  • [Polish]
  • [Experimental]

Note: Gaps between patch versions are faulty/broken releases. Note: A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice.

v3.2.29

  • Bug Fix
    • [typescript] fix interface's extend signature, #329 (@apepper)

v3.2.28

  • Bug Fix
    • Enums.is() with an array value should always be false, #327 (@phorsuedzie)

v3.2.27

  • Bug Fix
    • struct typescript extend signature, #317 (@lramel)
    • defaultProps missing from StructOptions, #317 (@lramel)

v3.2.25

  • Bug Fix
    • fromJSON makes use of defaultProps while deserializing a struct, fix #312 (@rkmax)

v3.2.24

  • Bug Fix
    • Struct extension of a refinement of a struct now use the correct displayName, fix #297 (@gcanti)

v3.2.23

  • Bug Fix
    • declare: remove unnecessary limitation, fix #291 (@gcanti)

v3.2.22

  • Polish
    • Update TypeScript definitions to allow module augmentation (@RedRoserade)

v3.2.21

  • Bug Fix
    • TypeScript definition file: Nil should be void | null (@francescogior)

v3.2.20

  • Polish
    • add options (struct, interface) to typescript definition (@gcanti)

v3.2.19

  • Polish
    • add strict (struct, interface) to typescript definition (@gcanti)

v3.2.18

  • Bug Fix
    • fix define in typescript definition (@gcanti)

v3.2.17

  • Bug Fix
    • add missing t.Integer to typescript definition (@gcanti)

v3.2.16

  • Bug Fix
    • strict structs with additional methods should not throw on updating, fix #267 (@gcanti)

v3.2.15

  • New Feature
    • Added support for overwriting defaultProps in t.struct.extend, fix #257 (@tehnomaag)

v3.2.14

  • Bug Fix
    • replace instanceof Array with Array.isArray, fix #255 (@ewnd9)

v3.2.13

  • Bug Fix
    • fromJSON: typecasting of values inside t.intersection, fix #250 (@gcanti)

v3.2.12

  • Bug Fix
    • now interface doesn't filter additional props when props contain a struct, fix #245 (@gcanti)

v3.2.11

  • Bug Fix
    • allow declare'd unions with custom dispatch, fix #242 (@gcanti)

v3.2.10

  • Bug Fix
    • handle nully values in interface is function (@gcanti)

v3.2.9

  • New Feature
    • fromJSON: track error path, fix #235 (@gcanti)
  • Internal
    • change shallow copy in order to improve perfs (@gcanti)

v3.2.8

  • Bug Fix
    • mixing types and classes in a union throws, fix #232 (@gcanti)

v3.2.7

  • Bug Fix
    • add support for class constructors, fromJSON module (@gcanti)
    • type-check the value returned by a custom reviver, fromJSON module (@gcanti)

v3.2.6

  • Bug Fix
    • null Maybes should stringify to null, fix #227 (@gcanti)

v3.2.5

  • Polish
    • prevent bugs when enums are defined through t.declare (@gcanti)

v3.2.4

  • Polish
    • decouple usage of new operator in create() function, fix #223 (@gcanti)

v3.2.3

  • Polish
    • add isNil check in interface constructor
  • Experimental

v3.2.2

  • Bug Fix
    • relax isObject contraint in interface combinator, fix #214

v3.2.1

  • Bug Fix
    • fix missing path argument in FuncType
  • Polish
    • better stringify serialization for functions

v3.2.0

v3.1.0

  • New Feature
    • add t.Integer to standard types
    • add t.Type to standard types
    • interface combinator, fix #195, docs (thanks @ctrlplusb)
      • add interface support to fromJSON (@minedeljkovic)
    • add support for extending refinements, fix #179, docs
    • local and global strict option for structs and interfaces, fix #203, docs
    • Chrome Dev Tools custom formatter for tcomb types docs
  • Bug Fix
    • More intelligent immutability update handling, fix #199 (thanks @ctrlplusb)
    • func combinator: support optional arguments, fix #198 (thanks @ivan-kleshnin)
  • Internal
    • add "Struct" prefix to structs default name
    • mixin() now allows identical references for overlapping properties

v3.0.0

Warning. If you don't rely in your codebase on the property maybe(MyType)(undefined) === null this is not a breaking change for you.

  • Breaking Change
    • prevent Maybe constructor from altering the value when Nil, fix #183 (thanks @gabro)

v2.7.0

  • New Feature
    • lib/fromJSON module: generic deserialize, fix #169
    • lib/fromJSON TypeScript definition file
  • Bug Fix
    • t.update module: $apply doesn't play well with dates and regexps, fix #172
    • t.update: cannot $merge and $remove at once, fix #170 (thanks @grahamlyus)
    • TypeScript: fix Exported external package typings file '...' is not a module
    • misleading error message in Struct.extend functions, fix #177 (thanks @Firfi)

v2.6.0

  • New Feature
    • declare API: recursive and mutually recursive types (thanks @utaal)
    • typescript definition file, fix #160 (thanks @DanielRosenwasser)
    • t.struct.extend, fix #164 (thanks @dzdrazil)
  • Internal
    • split main file to separate modules, fix #158
    • add "typings" field to package.json (TypeScript)
    • add predicate field to irreducibles meta objects
  • Documentation

v2.5.2

  • Bug Fix
    • remove the assert checking if the type returned by a union dispatch function is correct (was causing issues with unions of unions or unions of intersections)

v2.5.1

  • Internal
    • t.update should not change the reference when no changes occur, fix #153

v2.5.0

  • New Feature
    • check if the type returned by a union dispatch function is correct, fix #136 (thanks @fcracker79)
    • added refinement alias to subtype (which is deprecated), fix #140
  • Internal
    • optimisations: for identity types return early in production, fix #135 (thanks @fcracker79)
    • exposed getDefaultName on combinator constructors

v2.4.1

  • New Feature
    • added struct multiple inheritance, fix #143

v2.4.0

  • New Feature
    • unions
      • added update function, #127
      • the default dispatch implementation now handles unions of unions, #126
      • show the offended union type in error messages

v2.3.0

  • New Feature

    • Add support for lazy messages in asserts, fix #124
    • Better error messages for assert failures, fix #120

    The messages now have the following general form:

    Invalid value <value> supplied to <context>

    where context is a slash-separated string with the following properties:

    • the first element is the name of the "root"
    • the following elements have the form: <field name>: <field type>

    Note: for more readable messages remember to give types a name

    Example:

    var Person = t.struct({
      name: t.String
    }, 'Person'); // <- remember to give types a name
    
    var User = t.struct({
      email: t.String,
      profile: Person
    }, 'User');
    
    var mynumber = t.Number('a');
    // => Invalid value "a" supplied to Number
    
    var myuser = User({ email: 1 });
    // => Invalid value 1 supplied to User/email: String
    
    myuser = User({ email: 'email', profile: { name: 2 } });
    // => Invalid value 2 supplied to User/profile: Person/name: String

v2.2.1

  • Experimental
    • pattern matching #121

v2.2.0

  • New Feature

    • added intersection combinator fix #111

      Example

      const Min = t.subtype(t.String, function (s) { return s.length > 2; }, 'Min');
      const Max = t.subtype(t.String, function (s) { return s.length < 5; }, 'Max');
      const MinMax = t.intersection([Min, Max], 'MinMax');
      
      MinMax.is('abc'); // => true
      MinMax.is('a'); // => false
      MinMax.is('abcde'); // => false
  • Internal

    • optimised the generation of default names for types

v2.1.0

  • New Feature
    • added aliases for pre-defined irreducible types fix #112
    • added overridable stringify function to handle error messages and improve performances in development (replaces the experimental options.verbose)

v2.0.1

  • Experimental
    • added options.verbose (default true) to handle messages (set options.verbose = false to improve performances in development)

v2.0.0

  • New Feature
    • add support to types defined as ES6 classes #99
    • optimized for production code: asserts and freeze only in development mode
    • add is(x, type) function
    • add isType(x) function
    • add stringify(x) function
  • Breaking change
    • numeric types on enums #93 (thanks @m0x72)
    • remove asserts when process.env.NODE_ENV === 'production' #100
    • do not freeze if process.env.NODE_ENV === 'production' #103
    • func without currying #96 (thanks @tmcw)
    • remove useless exports #104
    • drop bower support #101
    • remove useless exports
      • Type
      • slice
      • shallowCopy
      • getFunctionName