elm-types Strawman

import t from 'elm-types';
const AddTodo = t.Constructor('AddTodo', [t.String]);
const RemoveTodo = t.Constructor('AddTodo', [t.String]);
const Action = t.Union('Action', [AddTodo]);
const Todo = t.Record('Todo', {
name: t.String,
completed: t.Bool
});
const Model = t.Record('Model', {
todos: t.List('todos', Todo)
});
// Throws if function is not passed correct parameter types
const update = t.Function('update', [Model, Action, Model], (state, action) =>
// Throws if last object is not exaustive
t.case(action, Action, {
[AddTodo]: add => ({
...state,
todos: [...state.todos, Todo(add, false)]
}),
[RemoveTodo]: remove => ({
...state,
todos: state.todos.filter(todo => todo.name === remove)
})
});
);
const store = createStore(update, Model([]));
const App = ({ todos }) => (
<div>
<h1>Todo List</h1>
<ul>
{todos.map(todo => (
<li onClick={() => store.dispatch(RemoveTodo(todo.name))}>
{todo.name}
</li>
))}
</ul>
</div>
);
const AppProps = t.Record('AppProps', {
todos: t.List('todos', Todo)
});
App.propTypes = t.PropTypes(AppProps);
render(
<App {...store.getState()} />,
document.getElementById('app')
);
with-react-redux.js