gcanti/babel-plugin-tcomb is tracked by TopGit as an open-source project, with 479 stars on GitHub, written primarily in JavaScript. Babel plugin for static and runtime type checking using Flow and tcomb
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
Babel plugin for static and runtime type checking using Flow and tcomb.
Tools
Flow is a static type checker for JavaScript.
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.
Why?
Runtime type checking (tcomb)
you don't want or you can't use Flow
you want refinement types
you want to validate the IO boundary (for example API payloads)
you want to enforce immutability
you want to leverage the runtime type introspection provided by tcomb's types
Static type checking (Flow)
babel-plugin-tcomb is Flow compatible, this means that you can run them side by side, statically checking your code with Flow and let tcomb catching the remaining bugs at runtime.
Gentle migration path
You can add type safety to your untyped codebase gradually:
first, add type annotations where you think they are most useful, file by file, leveraging the runtime type safety provided by tcomb
then, when you feel comfortable, turn on Flow and unleash the power of static type checking
third, for even more type safety, define your refinement types and validate the IO boundary
Fork
Here you can find a fork of this plugin that provides the following additional features:
Note. syntax-flow and transform-flow-strip-types are already included with the React Preset.
Note. Use Babel's env option to only use this plugin in development.
Warning. If you use multiple presets and are experiencing issues, try tweaking the preset order and setting passPerPreset: true. Related issues: #78 #99
Important. tcomb must be requireable
Plugin configuration
skipAsserts?: boolean = false
Removes the asserts and keeps the domain models
warnOnFailure?: boolean = false
Warns (console.warn) about type mismatch instead of throwing an error
globals?: Array<Object>
With this option you can handle global types, like Class or react SyntheticEvent
Definition files for tcomb and tcomb-react are temporarily published here.
Caveats
tcomb must be requireable
type parameters (aka generics) are not handled (Flow's responsibility)
How it works
First, add type annotations.
// index.js
function sum(a: number, b: number) {
return a + b
}
sum(1, 'a') // <= typo
Then run Flow (static type checking):
index.js:7
7: sum(1, 'a')
^^^^^^^^^^^ function call
7: sum(1, 'a')
^^^ string. This type is incompatible with
3: function sum(a: number, b: number) {
^^^^^^ number
or refresh your browser and look at the console (runtime type checking):
Uncaught TypeError: [tcomb] Invalid value "a" supplied to b: Number
index.js:14
14: getFullName({
^ function call
10: function getFullName(person: Person) {
^^^^^^ property `name`. Property not found in
14: getFullName({
^ object literal
tcomb:
TypeError: [tcomb] Invalid value undefined supplied to person: Person/name: String
Refinements
In order to define refinement types you can use the $Refinement type, providing a predicate identifier:
import type { $Refinement } from 'tcomb'
// define your predicate...
const isInteger = n => n % 1 === 0
// ...and pass it to the suitable intersection type
type Integer = number & $Refinement<typeof isInteger>;
function foo(n: Integer) {
return n
}
foo(2) // flow ok, tcomb ok
foo(2.1) // flow ok, tcomb throws [tcomb] Invalid value 2.1 supplied to n: Integer
foo('a') // flow throws, tcomb throws
In order to enable this feature add the tcomb definition file to the [libs] section of your .flowconfig.
Runtime type introspection
Check out the meta object in the tcomb documentation.
import type { $Reify } from 'tcomb'
type Person = { name: string };
const ReifiedPerson = (({}: any): $Reify<Person>)
console.log(ReifiedPerson.meta) // => { kind: 'interface', props: ... }
In order to enable this feature add the tcomb definition file to the [libs] section of your .flowconfig.
Validating (at runtime) the IO boundary using typecasts
type User = { name: string };
export function loadUser(userId: string): Promise<User> {
return axios.get('...').then(p => (p: User)) // <= type cast
}
import { createStore } from 'redux'
// types
type State = number;
type ReduxInitAction = { type: '@@redux/INIT' };
type Action = ReduxInitAction
| { type: 'INCREMENT', delta: number }
| { type: 'DECREMENT', delta: number };
function reducer(state: State = 0, action: Action): State {
switch(action.type) {
case 'INCREMENT' :
return state + action.delta
case 'DECREMENT' :
return state - action.delta
}
return state
}
type Store = {
dispatch: (action: Action) => any;
};
const store: Store = createStore(reducer)
store.dispatch({ type: 'INCREMEN', delta: 1 }) // <= typo
// throws [tcomb] Invalid value { "type": "INCREMEN", "delta": 1 } supplied to action: Action
// Flow throws as well
Type-checking React using tcomb-react
See tcomb-react:
// @flow
import React from 'react'
import ReactDOM from 'react-dom'
import { props } from 'tcomb-react'
type Props = {
name: string
};
@props(Props)
class Hello extends React.Component<void, Props, void> {
render() {
return <div>Hello {this.props.name}</div>
}
}
ReactDOM.render(<Hello />, document.getElementById('app'))
Flow will throw:
index.js:12
12: class Hello extends React.Component<void, Props, void> {
^^^^^ property `name`. Property not found in
19: ReactDOM.render(<Hello />, document.getElementById('app'))
^^^^^^^^^ props of React element `Hello`
while tcomb-react will warn:
Warning: Failed propType: [tcomb] Invalid prop "name" supplied to Hello, should be a String.
Detected errors (1):
1. Invalid value undefined supplied to String
In order to enable this feature add the tcomb-react definition file to the [libs] section of your .flowconfig.
Also you may want to set esproposal.decorators=ignore in the [options] section of your .flowconfig.
Without decorators
// @flow
import React from 'react'
import ReactDOM from 'react-dom'
import { propTypes } from 'tcomb-react'
import type { $Reify } from 'tcomb'
type Props = {
name: string
};
class Hello extends React.Component<void, Props, void> {
render() {
return <div>Hello {this.props.name}</div>
}
}
Hello.propTypes = propTypes((({}: any): $Reify<Props>))
ReactDOM.render(<Hello />, document.getElementById('app'))
Under the hood
Primitives
type MyString = string;
type MyNumber = number;
type MyBoolean = boolean;
type MyVoid = void;
type MyNull = null;
function sum(a: number, b: number): number {
return a + b
}
compiles to
import _t from "tcomb";
function sum(a, b) {
_assert(a, _t.Number, "a");
_assert(b, _t.Number, "b");
const ret = function (a, b) {
return a + b;
}.call(this, a, b);
_assert(ret, _t.Number, "return value");
return ret;
}
where _assert is an helper function injected by babel-plugin-tcomb.
Type aliases
type Person = {
name: string,
surname: ?string,
age: number,
tags: Array<string>
};
compiles to
import _t from "tcomb";
const Person = _t.interface({
name: _t.String,
surname: _t.maybe(_t.String),
age: _t.Number,
tags: _t.list(_t.String)
}, "Person");
Does gcanti/babel-plugin-tcomb have a project website?
No homepage URL was recorded for gcanti/babel-plugin-tcomb in TopGit's last sync. The README tab above frequently contains screenshots and demo links, or check the repository description on GitHub.
Does gcanti/babel-plugin-tcomb have any tags?
TopGit's last sync did not record any GitHub topics for gcanti/babel-plugin-tcomb. GitHub topics appear in the right sidebar of a repository page; that's the authoritative place to check.
How active is development on gcanti/babel-plugin-tcomb?
The most recent commit recorded on gcanti/babel-plugin-tcomb was 7.0 years ago, based on the GitHub push timestamp. The repository has 22 forks — one of the better signals of community interest.
How many stars does gcanti/babel-plugin-tcomb have?
gcanti/babel-plugin-tcomb has 479 GitHub stars — refresh the page for the live number, or check github.com/gcanti/babel-plugin-tcomb. TopGit mirrors GitHub's count but does not claim minute-by-minute accuracy.
What language is gcanti/babel-plugin-tcomb written in?
gcanti/babel-plugin-tcomb is written primarily in JavaScript. GitHub's language field is based on the largest share of bytes in the default branch.
What license does gcanti/babel-plugin-tcomb use?
gcanti/babel-plugin-tcomb is released under the MIT license. Always verify the LICENSE file directly on GitHub for the authoritative terms — license strings can be edited out of sync with a project's actual stance.
Where do I read more about gcanti/babel-plugin-tcomb?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/gcanti/babel-plugin-tcomb is the definitive source.
Read full README in the tab above.
Still deciding about babel-plugin-tcomb?
One click hands the question to an AI along with this page — see what it says about babel-plugin-tcomb.