Skip to content

Instantly share code, notes, and snippets.

@gcanti
Created August 25, 2018 13:37
Show Gist options
  • Save gcanti/6c178fb79e2bbc273796e7263d2ebcf1 to your computer and use it in GitHub Desktop.
Save gcanti/6c178fb79e2bbc273796e7263d2ebcf1 to your computer and use it in GitHub Desktop.
Automatically building a form from a `io-ts` type
import * as t from 'io-ts'
import * as React from 'react'
import { render } from 'react-dom'
type Field = t.StringType | t.NumberType | t.BooleanType
interface Form extends t.InterfaceType<{ [key: string]: Field }> {}
const toReactElement = (f: Form | Field): React.ReactElement<any> => {
// f is a tagged union
switch (f._tag) {
case 'StringType':
return <input type="text" />
case 'NumberType':
return <input type="number" />
case 'BooleanType':
return <input type="checkbox" />
case 'InterfaceType':
const inputs = Object.keys(f.props).map(k => <div key={k}>{toReactElement(f.props[k])}</div>)
return <fieldset>{inputs}</fieldset>
}
}
const Person = t.type({
name: t.string,
age: t.number,
rememberMe: t.boolean
})
/*
This will output 2 textboxes and 1 checkbox
*/
render(toReactElement(Person), document.getElementById('app'))
/*
Form correctness is checked statically
*/
toReactElement(t.type({ foo: t.array(t.string) })) // static error
@safareli
Copy link

me: this is not possible in new version of IO-ts right?
gcanti: Right, doing reflection like that is not possible anymore. Maybe you can do something similar with a Schema-like approach

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment