7,416 karma · joined October 23, 2009
Email: charles@codemix.com
type User = {name: string, isAdmin: boolean};
// compiles to
const User = t.object(
t.property('name', t.string()),
t.property('isAdmin', t.boolean())
);
// which you can then use with
User.check({name: 'Alice'}); // boolean
User.assert({nom: false}); // throws
Ultimately it should be possible to use this to implement pattern matching in JS based on flow types, for example: type User = {
name: string;
roles: Role[];
};
type Role = {
id: number;
name: string;
users: User[]
};
const url = match(someInput,
(user: User) => `/users/${user.name}`,
(role: Role) => `/roles/${role.id}`,
(_) => `/` // default URL
);
The really hard thing is to do this whilst maintaining perfect compatibility with flow.Actually kind of the opposite - babel used to use the common ESTree AST format, but they've moved away to something similar but incompatible.
Contracts are useful during development, they're typically stripped out in production builds, so there's no performance overhead there. If you find a bug in production, turn on your contracts and you'll quickly discover the source of the error. Contracts can validate the state of the world at runtime in a way that can never be covered by unit tests, unless your tests cover all possible inputs to your program. It doesn't mean you don't need unit tests too, they are yet another layer of safety.
I use this in combination with Flow, which means I have to transpile regardless, so the overhead is very low for me. Of course I'd like them to be part of the language proper, but for that to happen there needs to be developer demand first.
This thing can be used alongside Flow[0] and other babel plugins which use flow syntax.
Here's a Babel plugin which adds design by contract to JavaScript, squeezing it into existing JS syntax (the result is really similar to Eiffel) - https://github.com/codemix/babel-plugin-contracts
and here's what it looks like in a reasonably complicated program - https://github.com/codemix/malloc/blob/master/src/index.js
(disclosure: I wrote this)
<JavaScript src={`[1, 2, 3].map(n => n + 1)`} />[0] https://github.com/petkaantonov/bluebird/blob/master/docs/do...