Alternative syntax for prop types powered by io-ts
The @props
decorator sets propTypes
on the target component to use a
custom validator function built around
io-ts
types.
import * as React from 'react' import * as t from 'io-ts' import { props } from 'prop-types-ts' // define the runtime types const AlertType = t.keyof( { success: true, warning: true, info: true }, 'AlertType' ) const RuntimeProps = t.interface( { type: AlertType }, 'Props' ) // extract the static type export type Props = t.TypeOf<typeof RuntimeProps> // same as type Props = { type: 'success' | 'warning' | 'info' } @props(RuntimeProps) export default class Alert extends React.Component<Props, void> { render() { return <div>{this.props.children}</div> } }
import { getPropTypes } from 'prop-types-ts' ... export default class Alert extends React.Component<Props, void> { static propTypes = getPropTypes(RuntimeProps) render() { return <div>{this.props.children}</div> } }
<Alert type="foo" /> // => Invalid value "foo" supplied to : Props/type: AlertType
<Alert type="info" foo="bar" /> // => Invalid additional prop(s): ["foo"]
By default prop-types-ts
performs excess property checks. You can opt-out passing an option
argument to props
@props(RuntimeProps, { strict: false }) export default class Alert extends React.Component<Props, void> { ... }
prop-types-ts
exports some useful pre-defined types:
ReactElement
ReactChild
ReactFragment
ReactNode
Use the children
option
@props(RuntimeProps, { children: t.string }) export default class Alert extends React.Component<Props, void> { ... } <Alert type="info">{1}</Alert>// => Invalid value 1 supplied to children: string <Alert type="info">hello</Alert>// no errors
You can use any io-ts type
import { props, ReactChild } from 'prop-types-ts' @props(RuntimeProps, { children: t.tuple([t.string, ReactChild]) }) export default class Alert extends React.Component<Props, void> { ... } <Alert type="info">hello</Alert>// => Invalid value "hello" supplied to children: [string, ReactChild] <Alert type="info">hello <b>world</b></Alert> // no errors
works for Component
s too
import * as t from 'io-ts' import { props, ReactElement } from 'prop-types-ts' const JSXButton = t.refinement(ReactElement, e => e.type === 'button', 'JSXButton') @props(RuntimeProps, { children: JSXButton }) export default class Alert extends React.Component<Props, void> { ... } <Alert type="info">hello</Alert>// => Invalid value "hello" supplied to children: JSXButton <Alert type="info"><button>Click me</button></Alert> // no errors
prop-type-ts version |
required typescript version |
---|---|
0.7.x+ | 3.5+ |
0.6.x+ | 3.2+ |