node package manager

babel-plugin-flow-react-proptypes

A babel plugin to generate React PropTypes definitions from Flow type declarations.

build status Coverage Status npm version npm downloads Dependency Status

Example

With this input:

var React = require('react');
 
export type Qux = {baz: 'literal'};
 
import type SomeExternalType from './types';
 
type FooProps = {
  an_optional_string?: string,
  a_number: number,
  a_boolean: boolean,
  a_generic_object: Object,
  array_of_strings: Array<string>,
  instance_of_Bar: Bar,
  anything: any,
  mixed: mixed,
  one_of: 'QUACK' | 'BARK' | 5,
  one_of_type: number | string,
  nested_object_level_1: {
    string_property_1: string,
    nested_object_level_2: {
      nested_object_level_3: {
        string_property_3: string,
      },
      string_property_2: string,
    }
  },
  should_error_if_provided: void,
  intersection: {foo: string} & { bar: number } & Qux,
  some_external_type: SomeExternalType,
  some_external_type_intersection: {foo: string} & SomeExternalType,
}
 
export default class Foo extends React.Component {
  props: FooProps
}}

The output will be:

var React = require('react');
 
if (typeof exports !== 'undefined')
  Object.defineProperty(exports, 'babelPluginFlowReactPropTypes_proptype_Qux', {
    value: {
      baz: require('prop-types').oneOf(['literal']).isRequired,
    },
  });
 
var babelPluginFlowReactPropTypes_proptype_SomeExternalType = require('./types').babelPluginFlowReactPropTypes_proptype_SomeExternalType ||
  require('prop-types').any;
 
var Foo = (function(_React$Component) {
  // babel class boilerplate 
})(React.Component);
 
Foo.propTypes = {
  an_optional_string: require('prop-types').string,
  a_number: require('prop-types').number.isRequired,
  a_boolean: require('prop-types').bool.isRequired,
  a_generic_object: require('prop-types').object.isRequired,
  array_of_strings: require('prop-types').arrayOf(require('prop-types').string).isRequired,
  instance_of_Bar: typeof Bar === 'function'
    ? require('prop-types').instanceOf(Bar).isRequired
    : require('prop-types').any.isRequired,
  anything: require('prop-types').any.isRequired,
  mixed: require('prop-types').any.isRequired,
  one_of: require('prop-types').oneOf(['QUACK', 'BARK', 5]).isRequired,
  one_of_type: require('prop-types').oneOfType([require('prop-types').number, require('prop-types').string]).isRequired,
  nested_object_level_1: require('prop-types').shape({
    string_property_1: require('prop-types').string.isRequired,
    nested_object_level_2: require('prop-types').shape({
      nested_object_level_3: require('prop-types').shape({
        string_property_3: require('prop-types').string.isRequired,
      }).isRequired,
      string_property_2: require('prop-types').string.isRequired,
    }).isRequired,
  }).isRequired,
  should_error_if_provided: function should_error_if_provided(props, propName, componentName) {
    if (props[propName] != null)
      return new Error(
        'Invalid prop `' +
          propName +
          '` of value `' +
          value +
          '` passed to `' +
          componentName +
          '`. Expected undefined or null.'
      );
  },
  intersection: require('prop-types').shape({
    foo: require('prop-types').string.isRequired,
    bar: require('prop-types').number.isRequired,
    baz: require('prop-types').oneOf(['literal']).isRequired,
  }).isRequired,
  some_external_type: typeof babelPluginFlowReactPropTypes_proptype_SomeExternalType === 'function'
    ? babelPluginFlowReactPropTypes_proptype_SomeExternalType
    : require('prop-types').shape(babelPluginFlowReactPropTypes_proptype_SomeExternalType).isRequired,
  some_external_type_intersection: require('prop-types').shape(
    Object.assign(
      {},
      {foo: require('prop-types').string.isRequired,},
      babelPluginFlowReactPropTypes_proptype_SomeExternalType === require('prop-types').any
        ? {}
        : babelPluginFlowReactPropTypes_proptype_SomeExternalType
    )
  ).isRequired,
};
exports.default = Foo;

Usage

This plugin searches for a React components using type declaration. Works with functional components and ES6 classes. React.createClass is not currently supported.

Install

First install the plugin:

npm install --save-dev babel-plugin-flow-react-proptypes

Also install the prop-types package. This is required for React >=15.5.0. For earlier React versions you can use version 0.21.0 of this plugin, which doesn't use the prop-types pacakge.

npm install --save prop-types

Then add it to your babelrc:

{
  "presets": ["..."],
  "plugins": ["flow-react-proptypes"]
}

To save some bytes in production, you can also only enable it in development mode.

{
  "presets": ["..."],
  "env": {
    "development": {
      "plugins": ["flow-react-proptypes"]
    }
  }
}

Suppression

This plugin isn't perfect. You can disable it for an entire file with this directive (including quotes):

'no babel-plugin-flow-react-proptypes';

Specifically for react-native you can disable this for files in node_modules with the ignoreNodeModules config option.

{
  "presets": ["..."],
  "plugins": [["flow-react-proptypes", {"ignoreNodeModules": true}]]
}

If you already have other plugins in plugins section. It is important to place flow-react-proptypes before the following plugins:

  • transform-class-properties
  • transform-flow-strip-types

If you're using the 'react' or 'flow' presets, you don't need to do anything special.