React exports a handful of utility types that may be useful to you when typing
advanced React patterns. In previous sections we have seen a few of them. The
following is a complete reference for each of these types along with some
examples for how/where to use them.
Table of contents:
These types are all exported as named type exports from the react
module. If
you want to access them as members on the React
object (e.g.
React.Node
or
React.StatelessFunctionalComponent
) and
you are importing React as an ES module then you should import React
as a
namespace:
1
|
import * as React from 'react';
|
{"value":"import * as React from 'react';\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_MULT","context":"normal","value":"*","line":1,"start":7,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"as","line":1,"start":9,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":12,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":18,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":23,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31}],"errors":[]}
If you are using CommonJS you can also require React:
1
|
const React = require('react');
|
{"value":"const React = require('react');\n","tokens":[{"type":"T_CONST","context":"normal","value":"const","line":1,"start":0,"end":5},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":6,"end":11},{"type":"T_ASSIGN","context":"normal","value":"=","line":1,"start":12,"end":13},{"type":"T_IDENTIFIER","context":"normal","value":"require","line":1,"start":14,"end":21},{"type":"T_LPAREN","context":"normal","value":"(","line":1,"start":21,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":22,"end":29},{"type":"T_RPAREN","context":"normal","value":")","line":1,"start":29,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31}],"errors":[]}
You can also use named type imports in either an ES module environment or a
CommonJS environment:
1
|
import type {Node} from 'react';
|
{"value":"import type {Node} from 'react';\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":7,"end":11},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":12,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"Node","line":1,"start":13,"end":17},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":17,"end":18},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":19,"end":23},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":24,"end":31},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":31,"end":32}],"errors":[]}
We will refer to all the types in the following reference as if we imported them
with:
1
|
import * as React from 'react';
|
{"value":"import * as React from 'react';\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_MULT","context":"normal","value":"*","line":1,"start":7,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"as","line":1,"start":9,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":12,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":18,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":23,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31}],"errors":[]}
Note: While importing React with a default import works:
import React from 'react';
You will have access to all of the values that React exports, but you will
not have access to the types documented below! This is because Flow will
not add types to a default export since the default export could be any value
(like a number). Flow will add exported named types to an ES namespace object
which you can get with import * as React from 'react'
since Flow knows if
you export a value with the same name as an exported type.
Again, if you import React with: import React from 'react'
you will be able
to access React.Component
, React.createElement()
, React.Children
, and
other JavaScript values. However, you will not be able to access
React.Node
, React.ChildrenArray
or
other Flow types. You will need to use a named type import like:
import type {Node} from 'react'
in addition to your default import.
React.Node
This represents any node that can be rendered in a React application.
React.Node
can be null, a boolean, a number, a string, a React
element, or an array of any of those types recursively.
If you need a return type for your component render()
methods then you should use React.Node
.
However, if you need a generic type for a children prop, use ?React.Node
;
children can be undefined, when render()
can’t return undefined
.
Here is an example of React.Node
being used as the return type to render()
:
1
2
3
4
5
|
class MyComponent extends React.Component<{}> {
render(): React.Node {
}
}
|
{"value":"class MyComponent extends React.Component<{}> {\n render(): React.Node {\n // ...\n }\n}\n","tokens":[{"type":"T_CLASS","context":"normal","value":"class","line":1,"start":0,"end":5},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":1,"start":6,"end":17},{"type":"T_EXTENDS","context":"normal","value":"extends","line":1,"start":18,"end":25},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":26,"end":31},{"type":"T_PERIOD","context":"normal","value":".","line":1,"start":31,"end":32},{"type":"T_IDENTIFIER","context":"normal","value":"Component","line":1,"start":32,"end":41},{"type":"T_LESS_THAN","context":"type","value":"<","line":1,"start":41,"end":42},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":42,"end":43},{"type":"T_RCURLY","context":"type","value":"}","line":1,"start":43,"end":44},{"type":"T_GREATER_THAN","context":"type","value":">","line":1,"start":44,"end":45},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":46,"end":47},{"type":"T_IDENTIFIER","context":"normal","value":"render","line":2,"start":50,"end":56},{"type":"T_LPAREN","context":"normal","value":"(","line":2,"start":56,"end":57},{"type":"T_RPAREN","context":"normal","value":")","line":2,"start":57,"end":58},{"type":"T_COLON","context":"type","value":":","line":2,"start":58,"end":59},{"type":"T_IDENTIFIER","context":"type","value":"React","line":2,"start":60,"end":65},{"type":"T_PERIOD","context":"type","value":".","line":2,"start":65,"end":66},{"type":"T_IDENTIFIER","context":"type","value":"Node","line":2,"start":66,"end":70},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":71,"end":72},{"type":"Line","context":"comment","value":"// ...","line":3,"start":77,"end":83},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":86,"end":87},{"type":"T_RCURLY","context":"normal","value":"}","line":5,"start":88,"end":89}],"errors":[]}
It may also be used as the return type of a stateless functional component:
1
2
3
|
function MyComponent(props: {}): React.Node {
}
|
{"value":"function MyComponent(props: {}): React.Node {\n // ...\n}\n","tokens":[{"type":"T_FUNCTION","context":"normal","value":"function","line":1,"start":0,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":1,"start":9,"end":20},{"type":"T_LPAREN","context":"normal","value":"(","line":1,"start":20,"end":21},{"type":"T_IDENTIFIER","context":"normal","value":"props","line":1,"start":21,"end":26},{"type":"T_COLON","context":"type","value":":","line":1,"start":26,"end":27},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":28,"end":29},{"type":"T_RCURLY","context":"type","value":"}","line":1,"start":29,"end":30},{"type":"T_RPAREN","context":"normal","value":")","line":1,"start":30,"end":31},{"type":"T_COLON","context":"type","value":":","line":1,"start":31,"end":32},{"type":"T_IDENTIFIER","context":"type","value":"React","line":1,"start":33,"end":38},{"type":"T_PERIOD","context":"type","value":".","line":1,"start":38,"end":39},{"type":"T_IDENTIFIER","context":"type","value":"Node","line":1,"start":39,"end":43},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":44,"end":45},{"type":"Line","context":"comment","value":"// ...","line":2,"start":48,"end":54},{"type":"T_RCURLY","context":"normal","value":"}","line":3,"start":55,"end":56}],"errors":[]}
You don’t need to annotate the return type of either your render()
method or a
stateless functional component. However, if you want to annotate the return type
then React.Node
is the generic to use.
Here is an example of React.Node
as the prop type for children:
1
2
3
|
function MyComponent({ children }: { children: React.Node }) {
return <div>{children}</div>;
}
|
{"value":"function MyComponent({ children }: { children: React.Node }) {\n return <div>{children}</div>;\n}\n","tokens":[{"type":"T_FUNCTION","context":"normal","value":"function","line":1,"start":0,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":1,"start":9,"end":20},{"type":"T_LPAREN","context":"normal","value":"(","line":1,"start":20,"end":21},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":21,"end":22},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":1,"start":23,"end":31},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":32,"end":33},{"type":"T_COLON","context":"type","value":":","line":1,"start":33,"end":34},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":35,"end":36},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":1,"start":37,"end":45},{"type":"T_COLON","context":"type","value":":","line":1,"start":45,"end":46},{"type":"T_IDENTIFIER","context":"type","value":"React","line":1,"start":47,"end":52},{"type":"T_PERIOD","context":"type","value":".","line":1,"start":52,"end":53},{"type":"T_IDENTIFIER","context":"type","value":"Node","line":1,"start":53,"end":57},{"type":"T_RCURLY","context":"type","value":"}","line":1,"start":58,"end":59},{"type":"T_RPAREN","context":"normal","value":")","line":1,"start":59,"end":60},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":61,"end":62},{"type":"T_RETURN","context":"normal","value":"return","line":2,"start":65,"end":71},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":2,"start":72,"end":73},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":2,"start":73,"end":76},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":2,"start":76,"end":77},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":77,"end":78},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":2,"start":78,"end":86},{"type":"T_RCURLY","context":"normal","value":"}","line":2,"start":86,"end":87},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":2,"start":87,"end":88},{"type":"T_DIV","context":"jsxTag","value":"/","line":2,"start":88,"end":89},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":2,"start":89,"end":92},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":2,"start":92,"end":93},{"type":"T_SEMICOLON","context":"normal","value":";","line":2,"start":93,"end":94},{"type":"T_RCURLY","context":"normal","value":"}","line":3,"start":95,"end":96}],"errors":[]}
All react-dom
JSX intrinsics have React.Node
as their children type.
<div>
, <span>
, and all the rest.
The definition of React.Node
can be roughly approximated with a
React.ChildrenArray<T>
:
1
|
type Node = React.ChildrenArray<void | null | boolean | string | number | React.Element<any>>;
|
{"value":"type Node = React.ChildrenArray<void | null | boolean | string | number | React.Element<any>>;\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"Node","line":1,"start":5,"end":9},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":10,"end":11},{"type":"T_IDENTIFIER","context":"type","value":"React","line":1,"start":12,"end":17},{"type":"T_PERIOD","context":"type","value":".","line":1,"start":17,"end":18},{"type":"T_IDENTIFIER","context":"type","value":"ChildrenArray","line":1,"start":18,"end":31},{"type":"T_LESS_THAN","context":"type","value":"<","line":1,"start":31,"end":32},{"type":"T_VOID_TYPE","context":"type","value":"void","line":1,"start":32,"end":36},{"type":"T_BIT_OR","context":"type","value":"|","line":1,"start":37,"end":38},{"type":"T_NULL","context":"type","value":"null","line":1,"start":39,"end":43},{"type":"T_BIT_OR","context":"type","value":"|","line":1,"start":44,"end":45},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":1,"start":46,"end":53},{"type":"T_BIT_OR","context":"type","value":"|","line":1,"start":54,"end":55},{"type":"T_STRING_TYPE","context":"type","value":"string","line":1,"start":56,"end":62},{"type":"T_BIT_OR","context":"type","value":"|","line":1,"start":63,"end":64},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":1,"start":65,"end":71},{"type":"T_BIT_OR","context":"type","value":"|","line":1,"start":72,"end":73},{"type":"T_IDENTIFIER","context":"type","value":"React","line":1,"start":74,"end":79},{"type":"T_PERIOD","context":"type","value":".","line":1,"start":79,"end":80},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":1,"start":80,"end":87},{"type":"T_LESS_THAN","context":"type","value":"<","line":1,"start":87,"end":88},{"type":"T_ANY_TYPE","context":"type","value":"any","line":1,"start":88,"end":91},{"type":"T_GREATER_THAN","context":"type","value":">","line":1,"start":91,"end":92},{"type":"T_GREATER_THAN","context":"type","value":">","line":1,"start":92,"end":93},{"type":"T_SEMICOLON","context":"type","value":";","line":1,"start":93,"end":94}],"errors":[]}
React.Element<typeof Component>
A React element is the type for the value of a JSX element:
1
|
const element: React.Element<'div'> = <div />;
|
{"value":"const element: React.Element<'div'> = <div />;\n","tokens":[{"type":"T_CONST","context":"normal","value":"const","line":1,"start":0,"end":5},{"type":"T_IDENTIFIER","context":"normal","value":"element","line":1,"start":6,"end":13},{"type":"T_COLON","context":"type","value":":","line":1,"start":13,"end":14},{"type":"T_IDENTIFIER","context":"type","value":"React","line":1,"start":15,"end":20},{"type":"T_PERIOD","context":"type","value":".","line":1,"start":20,"end":21},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":1,"start":21,"end":28},{"type":"T_LESS_THAN","context":"type","value":"<","line":1,"start":28,"end":29},{"type":"T_STRING","context":"type","value":"'div'","line":1,"start":29,"end":34},{"type":"T_GREATER_THAN","context":"type","value":">","line":1,"start":34,"end":35},{"type":"T_ASSIGN","context":"normal","value":"=","line":1,"start":36,"end":37},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":38,"end":39},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":1,"start":39,"end":42},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":43,"end":44},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":44,"end":45},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":45,"end":46}],"errors":[]}
React.Element<typeof Component>
is also the return type of
React.createElement()
.
A React.Element<typeof Component>
takes a single type argument,
typeof Component
. typeof Component
is the component type of the React
element. For an intrinsic element, typeof Component
will be the string literal
for the intrinsic you used. Here are a few examples with DOM intrinsics:
1
2
3
|
(<div />: React.Element<'div'>);
(<span />: React.Element<'span'>);
(<div />: React.Element<'span'>);
|
{"value":"(<div />: React.Element<'div'>); // OK\n(<span />: React.Element<'span'>); // OK\n(<div />: React.Element<'span'>); // Error: div is not a span.\n","tokens":[{"type":"T_LPAREN","context":"normal","value":"(","line":1,"start":0,"end":1},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":1,"end":2},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":1,"start":2,"end":5},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":6,"end":7},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":7,"end":8},{"type":"T_COLON","context":"type","value":":","line":1,"start":8,"end":9},{"type":"T_IDENTIFIER","context":"type","value":"React","line":1,"start":10,"end":15},{"type":"T_PERIOD","context":"type","value":".","line":1,"start":15,"end":16},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":1,"start":16,"end":23},{"type":"T_LESS_THAN","context":"type","value":"<","line":1,"start":23,"end":24},{"type":"T_STRING","context":"type","value":"'div'","line":1,"start":24,"end":29},{"type":"T_GREATER_THAN","context":"type","value":">","line":1,"start":29,"end":30},{"type":"T_RPAREN","context":"normal","value":")","line":1,"start":30,"end":31},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":31,"end":32},{"type":"Line","context":"comment","value":"// OK","line":1,"start":33,"end":38},{"type":"T_LPAREN","context":"normal","value":"(","line":2,"start":39,"end":40},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":2,"start":40,"end":41},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"span","line":2,"start":41,"end":45},{"type":"T_DIV","context":"jsxTag","value":"/","line":2,"start":46,"end":47},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":2,"start":47,"end":48},{"type":"T_COLON","context":"type","value":":","line":2,"start":48,"end":49},{"type":"T_IDENTIFIER","context":"type","value":"React","line":2,"start":50,"end":55},{"type":"T_PERIOD","context":"type","value":".","line":2,"start":55,"end":56},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":2,"start":56,"end":63},{"type":"T_LESS_THAN","context":"type","value":"<","line":2,"start":63,"end":64},{"type":"T_STRING","context":"type","value":"'span'","line":2,"start":64,"end":70},{"type":"T_GREATER_THAN","context":"type","value":">","line":2,"start":70,"end":71},{"type":"T_RPAREN","context":"normal","value":")","line":2,"start":71,"end":72},{"type":"T_SEMICOLON","context":"normal","value":";","line":2,"start":72,"end":73},{"type":"Line","context":"comment","value":"// OK","line":2,"start":74,"end":79},{"type":"T_LPAREN","context":"normal","value":"(","line":3,"start":80,"end":81},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":3,"start":81,"end":82},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":3,"start":82,"end":85},{"type":"T_DIV","context":"jsxTag","value":"/","line":3,"start":86,"end":87},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":3,"start":87,"end":88},{"type":"T_COLON","context":"type","value":":","line":3,"start":88,"end":89},{"type":"T_IDENTIFIER","context":"type","value":"React","line":3,"start":90,"end":95},{"type":"T_PERIOD","context":"type","value":".","line":3,"start":95,"end":96},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":3,"start":96,"end":103},{"type":"T_LESS_THAN","context":"type","value":"<","line":3,"start":103,"end":104},{"type":"T_STRING","context":"type","value":"'span'","line":3,"start":104,"end":110},{"type":"T_GREATER_THAN","context":"type","value":">","line":3,"start":110,"end":111},{"type":"T_RPAREN","context":"normal","value":")","line":3,"start":111,"end":112},{"type":"T_SEMICOLON","context":"normal","value":";","line":3,"start":112,"end":113},{"type":"Line","context":"comment","value":"// Error: div is not a span.","line":3,"start":114,"end":142}],"errors":[]}
typeof Component
can also be your React class component or stateless
functional component.
1
2
3
4
5
6
|
class Foo extends React.Component<{}> {}
function Bar(props: {}) {}
(<Foo />: React.Element<typeof Foo>);
(<Bar />: React.Element<typeof Bar>);
(<Foo />: React.Element<typeof Bar>);
|
{"value":"class Foo extends React.Component<{}> {}\nfunction Bar(props: {}) {}\n\n(<Foo />: React.Element<typeof Foo>); // OK\n(<Bar />: React.Element<typeof Bar>); // OK\n(<Foo />: React.Element<typeof Bar>); // Error: Foo is not Bar\n","tokens":[{"type":"T_CLASS","context":"normal","value":"class","line":1,"start":0,"end":5},{"type":"T_IDENTIFIER","context":"normal","value":"Foo","line":1,"start":6,"end":9},{"type":"T_EXTENDS","context":"normal","value":"extends","line":1,"start":10,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":18,"end":23},{"type":"T_PERIOD","context":"normal","value":".","line":1,"start":23,"end":24},{"type":"T_IDENTIFIER","context":"normal","value":"Component","line":1,"start":24,"end":33},{"type":"T_LESS_THAN","context":"type","value":"<","line":1,"start":33,"end":34},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":34,"end":35},{"type":"T_RCURLY","context":"type","value":"}","line":1,"start":35,"end":36},{"type":"T_GREATER_THAN","context":"type","value":">","line":1,"start":36,"end":37},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":38,"end":39},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":39,"end":40},{"type":"T_FUNCTION","context":"normal","value":"function","line":2,"start":41,"end":49},{"type":"T_IDENTIFIER","context":"normal","value":"Bar","line":2,"start":50,"end":53},{"type":"T_LPAREN","context":"normal","value":"(","line":2,"start":53,"end":54},{"type":"T_IDENTIFIER","context":"normal","value":"props","line":2,"start":54,"end":59},{"type":"T_COLON","context":"type","value":":","line":2,"start":59,"end":60},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":61,"end":62},{"type":"T_RCURLY","context":"type","value":"}","line":2,"start":62,"end":63},{"type":"T_RPAREN","context":"normal","value":")","line":2,"start":63,"end":64},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":65,"end":66},{"type":"T_RCURLY","context":"normal","value":"}","line":2,"start":66,"end":67},{"type":"T_LPAREN","context":"normal","value":"(","line":4,"start":69,"end":70},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":4,"start":70,"end":71},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Foo","line":4,"start":71,"end":74},{"type":"T_DIV","context":"jsxTag","value":"/","line":4,"start":75,"end":76},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":4,"start":76,"end":77},{"type":"T_COLON","context":"type","value":":","line":4,"start":77,"end":78},{"type":"T_IDENTIFIER","context":"type","value":"React","line":4,"start":79,"end":84},{"type":"T_PERIOD","context":"type","value":".","line":4,"start":84,"end":85},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":4,"start":85,"end":92},{"type":"T_LESS_THAN","context":"type","value":"<","line":4,"start":92,"end":93},{"type":"T_TYPEOF","context":"type","value":"typeof","line":4,"start":93,"end":99},{"type":"T_IDENTIFIER","context":"type","value":"Foo","line":4,"start":100,"end":103},{"type":"T_GREATER_THAN","context":"type","value":">","line":4,"start":103,"end":104},{"type":"T_RPAREN","context":"normal","value":")","line":4,"start":104,"end":105},{"type":"T_SEMICOLON","context":"normal","value":";","line":4,"start":105,"end":106},{"type":"Line","context":"comment","value":"// OK","line":4,"start":107,"end":112},{"type":"T_LPAREN","context":"normal","value":"(","line":5,"start":113,"end":114},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":5,"start":114,"end":115},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Bar","line":5,"start":115,"end":118},{"type":"T_DIV","context":"jsxTag","value":"/","line":5,"start":119,"end":120},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":5,"start":120,"end":121},{"type":"T_COLON","context":"type","value":":","line":5,"start":121,"end":122},{"type":"T_IDENTIFIER","context":"type","value":"React","line":5,"start":123,"end":128},{"type":"T_PERIOD","context":"type","value":".","line":5,"start":128,"end":129},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":5,"start":129,"end":136},{"type":"T_LESS_THAN","context":"type","value":"<","line":5,"start":136,"end":137},{"type":"T_TYPEOF","context":"type","value":"typeof","line":5,"start":137,"end":143},{"type":"T_IDENTIFIER","context":"type","value":"Bar","line":5,"start":144,"end":147},{"type":"T_GREATER_THAN","context":"type","value":">","line":5,"start":147,"end":148},{"type":"T_RPAREN","context":"normal","value":")","line":5,"start":148,"end":149},{"type":"T_SEMICOLON","context":"normal","value":";","line":5,"start":149,"end":150},{"type":"Line","context":"comment","value":"// OK","line":5,"start":151,"end":156},{"type":"T_LPAREN","context":"normal","value":"(","line":6,"start":157,"end":158},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":6,"start":158,"end":159},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Foo","line":6,"start":159,"end":162},{"type":"T_DIV","context":"jsxTag","value":"/","line":6,"start":163,"end":164},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":6,"start":164,"end":165},{"type":"T_COLON","context":"type","value":":","line":6,"start":165,"end":166},{"type":"T_IDENTIFIER","context":"type","value":"React","line":6,"start":167,"end":172},{"type":"T_PERIOD","context":"type","value":".","line":6,"start":172,"end":173},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":6,"start":173,"end":180},{"type":"T_LESS_THAN","context":"type","value":"<","line":6,"start":180,"end":181},{"type":"T_TYPEOF","context":"type","value":"typeof","line":6,"start":181,"end":187},{"type":"T_IDENTIFIER","context":"type","value":"Bar","line":6,"start":188,"end":191},{"type":"T_GREATER_THAN","context":"type","value":">","line":6,"start":191,"end":192},{"type":"T_RPAREN","context":"normal","value":")","line":6,"start":192,"end":193},{"type":"T_SEMICOLON","context":"normal","value":";","line":6,"start":193,"end":194},{"type":"Line","context":"comment","value":"// Error: Foo is not Bar","line":6,"start":195,"end":219}],"errors":[]}
Take note of the typeof
, it is required! Foo
without typeof
would be the
type of an instance of Foo
. So: (new Foo(): Foo)
. We want the type of
Foo
not the type of an instance of Foo
. So: (Foo: typeof Foo)
.
Class<Foo>
would also work here, but we prefer typeof
for consistency with
stateless functional components.
We also need typeof
for Bar
because Bar
is a value. So we want to get the
type of the value Bar
. (Bar: Bar)
is an error because Bar
cannot be used
as a type, so the following is correct: (Bar: typeof Bar)
.
React.ChildrenArray<T>
A React children array can be a single value or an array nested to any level.
It is designed to be used with the React.Children
API.
For example if you want to get a normal JavaScript array from a
React.ChildrenArray<T>
see the following example:
1
2
3
4
5
6
7
8
9
|
import * as React from 'react';
const children: React.ChildrenArray<number> = 42;
const children: React.ChildrenArray<number> = [[1, 2], 3, [4, 5]];
const array: Array<number> = React.Children.toArray(children);
|
{"value":"import * as React from 'react';\n\n// A children array can be a single value...\nconst children: React.ChildrenArray<number> = 42;\n// ...or an arbitrarily nested array.\nconst children: React.ChildrenArray<number> = [[1, 2], 3, [4, 5]];\n\n// Using the `React.Children` API can flatten the array.\nconst array: Array<number> = React.Children.toArray(children);\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_MULT","context":"normal","value":"*","line":1,"start":7,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"as","line":1,"start":9,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":12,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":18,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":23,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31},{"type":"Line","context":"comment","value":"// A children array can be a single value...","line":3,"start":33,"end":77},{"type":"T_CONST","context":"normal","value":"const","line":4,"start":78,"end":83},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":4,"start":84,"end":92},{"type":"T_COLON","context":"type","value":":","line":4,"start":92,"end":93},{"type":"T_IDENTIFIER","context":"type","value":"React","line":4,"start":94,"end":99},{"type":"T_PERIOD","context":"type","value":".","line":4,"start":99,"end":100},{"type":"T_IDENTIFIER","context":"type","value":"ChildrenArray","line":4,"start":100,"end":113},{"type":"T_LESS_THAN","context":"type","value":"<","line":4,"start":113,"end":114},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":4,"start":114,"end":120},{"type":"T_GREATER_THAN","context":"type","value":">","line":4,"start":120,"end":121},{"type":"T_ASSIGN","context":"normal","value":"=","line":4,"start":122,"end":123},{"type":"T_NUMBER","context":"normal","value":"42","line":4,"start":124,"end":126},{"type":"T_SEMICOLON","context":"normal","value":";","line":4,"start":126,"end":127},{"type":"Line","context":"comment","value":"// ...or an arbitrarily nested array.","line":5,"start":128,"end":165},{"type":"T_CONST","context":"normal","value":"const","line":6,"start":166,"end":171},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":6,"start":172,"end":180},{"type":"T_COLON","context":"type","value":":","line":6,"start":180,"end":181},{"type":"T_IDENTIFIER","context":"type","value":"React","line":6,"start":182,"end":187},{"type":"T_PERIOD","context":"type","value":".","line":6,"start":187,"end":188},{"type":"T_IDENTIFIER","context":"type","value":"ChildrenArray","line":6,"start":188,"end":201},{"type":"T_LESS_THAN","context":"type","value":"<","line":6,"start":201,"end":202},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":6,"start":202,"end":208},{"type":"T_GREATER_THAN","context":"type","value":">","line":6,"start":208,"end":209},{"type":"T_ASSIGN","context":"normal","value":"=","line":6,"start":210,"end":211},{"type":"T_LBRACKET","context":"normal","value":"[","line":6,"start":212,"end":213},{"type":"T_LBRACKET","context":"normal","value":"[","line":6,"start":213,"end":214},{"type":"T_NUMBER","context":"normal","value":"1","line":6,"start":214,"end":215},{"type":"T_COMMA","context":"normal","value":",","line":6,"start":215,"end":216},{"type":"T_NUMBER","context":"normal","value":"2","line":6,"start":217,"end":218},{"type":"T_RBRACKET","context":"normal","value":"]","line":6,"start":218,"end":219},{"type":"T_COMMA","context":"normal","value":",","line":6,"start":219,"end":220},{"type":"T_NUMBER","context":"normal","value":"3","line":6,"start":221,"end":222},{"type":"T_COMMA","context":"normal","value":",","line":6,"start":222,"end":223},{"type":"T_LBRACKET","context":"normal","value":"[","line":6,"start":224,"end":225},{"type":"T_NUMBER","context":"normal","value":"4","line":6,"start":225,"end":226},{"type":"T_COMMA","context":"normal","value":",","line":6,"start":226,"end":227},{"type":"T_NUMBER","context":"normal","value":"5","line":6,"start":228,"end":229},{"type":"T_RBRACKET","context":"normal","value":"]","line":6,"start":229,"end":230},{"type":"T_RBRACKET","context":"normal","value":"]","line":6,"start":230,"end":231},{"type":"T_SEMICOLON","context":"normal","value":";","line":6,"start":231,"end":232},{"type":"Line","context":"comment","value":"// Using the `React.Children` API can flatten the array.","line":8,"start":234,"end":290},{"type":"T_CONST","context":"normal","value":"const","line":9,"start":291,"end":296},{"type":"T_IDENTIFIER","context":"normal","value":"array","line":9,"start":297,"end":302},{"type":"T_COLON","context":"type","value":":","line":9,"start":302,"end":303},{"type":"T_IDENTIFIER","context":"type","value":"Array","line":9,"start":304,"end":309},{"type":"T_LESS_THAN","context":"type","value":"<","line":9,"start":309,"end":310},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":9,"start":310,"end":316},{"type":"T_GREATER_THAN","context":"type","value":">","line":9,"start":316,"end":317},{"type":"T_ASSIGN","context":"normal","value":"=","line":9,"start":318,"end":319},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":9,"start":320,"end":325},{"type":"T_PERIOD","context":"normal","value":".","line":9,"start":325,"end":326},{"type":"T_IDENTIFIER","context":"normal","value":"Children","line":9,"start":326,"end":334},{"type":"T_PERIOD","context":"normal","value":".","line":9,"start":334,"end":335},{"type":"T_IDENTIFIER","context":"normal","value":"toArray","line":9,"start":335,"end":342},{"type":"T_LPAREN","context":"normal","value":"(","line":9,"start":342,"end":343},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":9,"start":343,"end":351},{"type":"T_RPAREN","context":"normal","value":")","line":9,"start":351,"end":352},{"type":"T_SEMICOLON","context":"normal","value":";","line":9,"start":352,"end":353}],"errors":[]}
React.AbstractComponent<Config, Instance>
React.AbstractComponent<Config, Instance>
(v0.89.0+) represents a component with
a config of type Config and instance of type Instance.
Instance is optional and is mixed by default.
A class or function component with config Config
may be used in places that expect
React.AbstractComponent<Config>
.
This is Flow’s most abstract representation of a React component, and is most useful for
writing HOCs and library definitions.
React.ComponentType<Props>
This is a union of a class component or a stateless functional component. This
is the type you want to use for functions that receive or return React
components such as higher-order components or other utilities.
Here is how you may use React.ComponentType<Props>
with
React.Element<typeof Component>
to construct a component
with a specific set of props:
1
2
3
4
5
6
7
8
9
10
|
type Props = {
foo: number,
bar: number,
};
function createMyElement<C: React.ComponentType<Props>>(
Component: C,
): React.Element<C> {
return <Component foo={1} bar={2} />;
}
|
{"value":"type Props = {\n foo: number,\n bar: number,\n};\n\nfunction createMyElement<C: React.ComponentType<Props>>(\n Component: C,\n): React.Element<C> {\n return <Component foo={1} bar={2} />;\n}\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":1,"start":5,"end":10},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":11,"end":12},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":13,"end":14},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":2,"start":17,"end":20},{"type":"T_COLON","context":"type","value":":","line":2,"start":20,"end":21},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":2,"start":22,"end":28},{"type":"T_COMMA","context":"type","value":",","line":2,"start":28,"end":29},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":3,"start":32,"end":35},{"type":"T_COLON","context":"type","value":":","line":3,"start":35,"end":36},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":3,"start":37,"end":43},{"type":"T_COMMA","context":"type","value":",","line":3,"start":43,"end":44},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":45,"end":46},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":46,"end":47},{"type":"T_FUNCTION","context":"normal","value":"function","line":6,"start":49,"end":57},{"type":"T_IDENTIFIER","context":"normal","value":"createMyElement","line":6,"start":58,"end":73},{"type":"T_LESS_THAN","context":"type","value":"<","line":6,"start":73,"end":74},{"type":"T_IDENTIFIER","context":"type","value":"C","line":6,"start":74,"end":75},{"type":"T_COLON","context":"type","value":":","line":6,"start":75,"end":76},{"type":"T_IDENTIFIER","context":"type","value":"React","line":6,"start":77,"end":82},{"type":"T_PERIOD","context":"type","value":".","line":6,"start":82,"end":83},{"type":"T_IDENTIFIER","context":"type","value":"ComponentType","line":6,"start":83,"end":96},{"type":"T_LESS_THAN","context":"type","value":"<","line":6,"start":96,"end":97},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":6,"start":97,"end":102},{"type":"T_GREATER_THAN","context":"type","value":">","line":6,"start":102,"end":103},{"type":"T_GREATER_THAN","context":"type","value":">","line":6,"start":103,"end":104},{"type":"T_LPAREN","context":"normal","value":"(","line":6,"start":104,"end":105},{"type":"T_IDENTIFIER","context":"normal","value":"Component","line":7,"start":108,"end":117},{"type":"T_COLON","context":"type","value":":","line":7,"start":117,"end":118},{"type":"T_IDENTIFIER","context":"type","value":"C","line":7,"start":119,"end":120},{"type":"T_COMMA","context":"normal","value":",","line":7,"start":120,"end":121},{"type":"T_RPAREN","context":"normal","value":")","line":8,"start":122,"end":123},{"type":"T_COLON","context":"type","value":":","line":8,"start":123,"end":124},{"type":"T_IDENTIFIER","context":"type","value":"React","line":8,"start":125,"end":130},{"type":"T_PERIOD","context":"type","value":".","line":8,"start":130,"end":131},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":8,"start":131,"end":138},{"type":"T_LESS_THAN","context":"type","value":"<","line":8,"start":138,"end":139},{"type":"T_IDENTIFIER","context":"type","value":"C","line":8,"start":139,"end":140},{"type":"T_GREATER_THAN","context":"type","value":">","line":8,"start":140,"end":141},{"type":"T_LCURLY","context":"normal","value":"{","line":8,"start":142,"end":143},{"type":"T_RETURN","context":"normal","value":"return","line":9,"start":146,"end":152},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":9,"start":153,"end":154},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Component","line":9,"start":154,"end":163},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"foo","line":9,"start":164,"end":167},{"type":"T_ASSIGN","context":"jsxTag","value":"=","line":9,"start":167,"end":168},{"type":"T_LCURLY","context":"normal","value":"{","line":9,"start":168,"end":169},{"type":"T_NUMBER","context":"normal","value":"1","line":9,"start":169,"end":170},{"type":"T_RCURLY","context":"normal","value":"}","line":9,"start":170,"end":171},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"bar","line":9,"start":172,"end":175},{"type":"T_ASSIGN","context":"jsxTag","value":"=","line":9,"start":175,"end":176},{"type":"T_LCURLY","context":"normal","value":"{","line":9,"start":176,"end":177},{"type":"T_NUMBER","context":"normal","value":"2","line":9,"start":177,"end":178},{"type":"T_RCURLY","context":"normal","value":"}","line":9,"start":178,"end":179},{"type":"T_DIV","context":"jsxTag","value":"/","line":9,"start":180,"end":181},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":9,"start":181,"end":182},{"type":"T_SEMICOLON","context":"normal","value":";","line":9,"start":182,"end":183},{"type":"T_RCURLY","context":"normal","value":"}","line":10,"start":184,"end":185}],"errors":[]}
React.ComponentType<Props>
does not include intrinsic JSX element types like
div
or span
. See React.ElementType
if you also want
to include JSX intrinsics.
The definition for React.ComponentType<Props>
is roughly:
1
2
3
|
type ComponentType<Props> =
| React.StatelessFunctionalComponent<Props>
| Class<React.Component<Props, any>>;
|
{"value":"type ComponentType<Props> =\n | React.StatelessFunctionalComponent<Props>\n | Class<React.Component<Props, any>>;\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"ComponentType","line":1,"start":5,"end":18},{"type":"T_LESS_THAN","context":"type","value":"<","line":1,"start":18,"end":19},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":1,"start":19,"end":24},{"type":"T_GREATER_THAN","context":"type","value":">","line":1,"start":24,"end":25},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":26,"end":27},{"type":"T_BIT_OR","context":"type","value":"|","line":2,"start":30,"end":31},{"type":"T_IDENTIFIER","context":"type","value":"React","line":2,"start":32,"end":37},{"type":"T_PERIOD","context":"type","value":".","line":2,"start":37,"end":38},{"type":"T_IDENTIFIER","context":"type","value":"StatelessFunctionalComponent","line":2,"start":38,"end":66},{"type":"T_LESS_THAN","context":"type","value":"<","line":2,"start":66,"end":67},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":2,"start":67,"end":72},{"type":"T_GREATER_THAN","context":"type","value":">","line":2,"start":72,"end":73},{"type":"T_BIT_OR","context":"type","value":"|","line":3,"start":76,"end":77},{"type":"T_IDENTIFIER","context":"type","value":"Class","line":3,"start":78,"end":83},{"type":"T_LESS_THAN","context":"type","value":"<","line":3,"start":83,"end":84},{"type":"T_IDENTIFIER","context":"type","value":"React","line":3,"start":84,"end":89},{"type":"T_PERIOD","context":"type","value":".","line":3,"start":89,"end":90},{"type":"T_IDENTIFIER","context":"type","value":"Component","line":3,"start":90,"end":99},{"type":"T_LESS_THAN","context":"type","value":"<","line":3,"start":99,"end":100},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":3,"start":100,"end":105},{"type":"T_COMMA","context":"type","value":",","line":3,"start":105,"end":106},{"type":"T_ANY_TYPE","context":"type","value":"any","line":3,"start":107,"end":110},{"type":"T_GREATER_THAN","context":"type","value":">","line":3,"start":110,"end":111},{"type":"T_GREATER_THAN","context":"type","value":">","line":3,"start":111,"end":112},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":112,"end":113}],"errors":[]}
Note: In 0.89.0+, React.ComponentType is an alias for React.AbstractComponent<Config, any>,
which represents a component with config type Config and any instance type.
React.StatelessFunctionalComponent<Props>
This is the type of a React stateless functional component.
The definition for React.StatelessFunctionalComponent<Props>
is roughly:
1
2
|
type StatelessFunctionalComponent<Props> =
(props: Props) => React.Node;
|
{"value":"type StatelessFunctionalComponent<Props> =\n (props: Props) => React.Node;\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"StatelessFunctionalComponent","line":1,"start":5,"end":33},{"type":"T_LESS_THAN","context":"type","value":"<","line":1,"start":33,"end":34},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":1,"start":34,"end":39},{"type":"T_GREATER_THAN","context":"type","value":">","line":1,"start":39,"end":40},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":41,"end":42},{"type":"T_LPAREN","context":"type","value":"(","line":2,"start":45,"end":46},{"type":"T_IDENTIFIER","context":"type","value":"props","line":2,"start":46,"end":51},{"type":"T_COLON","context":"type","value":":","line":2,"start":51,"end":52},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":2,"start":53,"end":58},{"type":"T_RPAREN","context":"type","value":")","line":2,"start":58,"end":59},{"type":"T_ARROW","context":"type","value":"=>","line":2,"start":60,"end":62},{"type":"T_IDENTIFIER","context":"type","value":"React","line":2,"start":63,"end":68},{"type":"T_PERIOD","context":"type","value":".","line":2,"start":68,"end":69},{"type":"T_IDENTIFIER","context":"type","value":"Node","line":2,"start":69,"end":73},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":73,"end":74}],"errors":[]}
There is a little bit more to the definition of
React.StatelessFunctionalComponent<Props>
for context and props.
React.ElementType
Similar to React.ComponentType<Props>
except it also
includes JSX intrinsics (strings).
The definition for React.ElementType
is roughly:
1
2
3
|
type ElementType =
| string
| React.ComponentType<any>;
|
{"value":"type ElementType =\n | string\n | React.ComponentType<any>;\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"ElementType","line":1,"start":5,"end":16},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":17,"end":18},{"type":"T_BIT_OR","context":"type","value":"|","line":2,"start":21,"end":22},{"type":"T_STRING_TYPE","context":"type","value":"string","line":2,"start":23,"end":29},{"type":"T_BIT_OR","context":"type","value":"|","line":3,"start":32,"end":33},{"type":"T_IDENTIFIER","context":"type","value":"React","line":3,"start":34,"end":39},{"type":"T_PERIOD","context":"type","value":".","line":3,"start":39,"end":40},{"type":"T_IDENTIFIER","context":"type","value":"ComponentType","line":3,"start":40,"end":53},{"type":"T_LESS_THAN","context":"type","value":"<","line":3,"start":53,"end":54},{"type":"T_ANY_TYPE","context":"type","value":"any","line":3,"start":54,"end":57},{"type":"T_GREATER_THAN","context":"type","value":">","line":3,"start":57,"end":58},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":58,"end":59}],"errors":[]}
React.Key
The type of the key prop on React elements. It is a union of strings and
numbers defined as:
1
|
type Key = string | number;
|
{"value":"type Key = string | number;\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"Key","line":1,"start":5,"end":8},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":9,"end":10},{"type":"T_STRING_TYPE","context":"type","value":"string","line":1,"start":11,"end":17},{"type":"T_BIT_OR","context":"type","value":"|","line":1,"start":18,"end":19},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":1,"start":20,"end":26},{"type":"T_SEMICOLON","context":"type","value":";","line":1,"start":26,"end":27}],"errors":[]}
React.Ref<typeof Component>
The type of the ref prop on React elements. React.Ref<typeof Component>
could be a string or a ref function.
The ref function will take one and only argument which will be the element
instance which is retrieved using
React.ElementRef<typeof Component>
or null since
React will pass null into a ref function when unmounting.
Like React.Element<typeof Component>
, typeof Component
must be the type of a React component so you need to use typeof
as in
React.Ref<typeof MyComponent>
.
The definition for React.Ref<typeof Component>
is roughly:
1
2
3
|
type Ref<C> =
| string
| (instance: React.ElementRef<C> | null) => mixed;
|
{"value":"type Ref<C> =\n | string\n | (instance: React.ElementRef<C> | null) => mixed;\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"Ref","line":1,"start":5,"end":8},{"type":"T_LESS_THAN","context":"type","value":"<","line":1,"start":8,"end":9},{"type":"T_IDENTIFIER","context":"type","value":"C","line":1,"start":9,"end":10},{"type":"T_GREATER_THAN","context":"type","value":">","line":1,"start":10,"end":11},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":12,"end":13},{"type":"T_BIT_OR","context":"type","value":"|","line":2,"start":16,"end":17},{"type":"T_STRING_TYPE","context":"type","value":"string","line":2,"start":18,"end":24},{"type":"T_BIT_OR","context":"type","value":"|","line":3,"start":27,"end":28},{"type":"T_LPAREN","context":"type","value":"(","line":3,"start":29,"end":30},{"type":"T_IDENTIFIER","context":"type","value":"instance","line":3,"start":30,"end":38},{"type":"T_COLON","context":"type","value":":","line":3,"start":38,"end":39},{"type":"T_IDENTIFIER","context":"type","value":"React","line":3,"start":40,"end":45},{"type":"T_PERIOD","context":"type","value":".","line":3,"start":45,"end":46},{"type":"T_IDENTIFIER","context":"type","value":"ElementRef","line":3,"start":46,"end":56},{"type":"T_LESS_THAN","context":"type","value":"<","line":3,"start":56,"end":57},{"type":"T_IDENTIFIER","context":"type","value":"C","line":3,"start":57,"end":58},{"type":"T_GREATER_THAN","context":"type","value":">","line":3,"start":58,"end":59},{"type":"T_BIT_OR","context":"type","value":"|","line":3,"start":60,"end":61},{"type":"T_NULL","context":"type","value":"null","line":3,"start":62,"end":66},{"type":"T_RPAREN","context":"type","value":")","line":3,"start":66,"end":67},{"type":"T_ARROW","context":"type","value":"=>","line":3,"start":68,"end":70},{"type":"T_MIXED_TYPE","context":"type","value":"mixed","line":3,"start":71,"end":76},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":76,"end":77}],"errors":[]}
React.ElementProps<typeof Component>
Gets the props for a React element type, without preserving the optionality of defaultProps
.
typeof Component
could be the type of a React class component, a stateless functional component, or a JSX intrinsic string.
This type is used for the props
property on React.Element<typeof Component>
.
Like React.Element<typeof Component>
, typeof Component
must be the
type of a React component so you need to use typeof
as in
React.ElementProps<typeof MyComponent>
.
Note: Because React.ElementProps
does not preserve the optionality of defaultProps
, React.ElementConfig
(which does) is more often the right choice, especially for simple props pass-through as with higher-order components.
React.ElementConfig<typeof Component>
Like React.ElementProps<typeof Component>
this utility gets the type of a
component’s props but preserves the optionality of defaultProps
!
For example,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import * as React from 'react';
class MyComponent extends React.Component<{foo: number}> {
static defaultProps = {foo: 42};
render() {
return this.props.foo;
}
}
({foo: 42}: React.ElementProps<typeof MyComponent>);
({}: React.ElementConfig<typeof MyComponent>);
|
{"value":"import * as React from 'react';\n\nclass MyComponent extends React.Component<{foo: number}> {\n static defaultProps = {foo: 42};\n\n render() {\n return this.props.foo;\n }\n}\n\n// `React.ElementProps<>` requires `foo` even though it has a `defaultProp`.\n({foo: 42}: React.ElementProps<typeof MyComponent>);\n\n// `React.ElementConfig<>` does not require `foo` since it has a `defaultProp`.\n({}: React.ElementConfig<typeof MyComponent>);\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_MULT","context":"normal","value":"*","line":1,"start":7,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"as","line":1,"start":9,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":12,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":18,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":23,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31},{"type":"T_CLASS","context":"normal","value":"class","line":3,"start":33,"end":38},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":3,"start":39,"end":50},{"type":"T_EXTENDS","context":"normal","value":"extends","line":3,"start":51,"end":58},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":3,"start":59,"end":64},{"type":"T_PERIOD","context":"normal","value":".","line":3,"start":64,"end":65},{"type":"T_IDENTIFIER","context":"normal","value":"Component","line":3,"start":65,"end":74},{"type":"T_LESS_THAN","context":"type","value":"<","line":3,"start":74,"end":75},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":75,"end":76},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":3,"start":76,"end":79},{"type":"T_COLON","context":"type","value":":","line":3,"start":79,"end":80},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":3,"start":81,"end":87},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":87,"end":88},{"type":"T_GREATER_THAN","context":"type","value":">","line":3,"start":88,"end":89},{"type":"T_LCURLY","context":"normal","value":"{","line":3,"start":90,"end":91},{"type":"T_STATIC","context":"normal","value":"static","line":4,"start":94,"end":100},{"type":"T_IDENTIFIER","context":"normal","value":"defaultProps","line":4,"start":101,"end":113},{"type":"T_ASSIGN","context":"normal","value":"=","line":4,"start":114,"end":115},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":116,"end":117},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":4,"start":117,"end":120},{"type":"T_COLON","context":"normal","value":":","line":4,"start":120,"end":121},{"type":"T_NUMBER","context":"normal","value":"42","line":4,"start":122,"end":124},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":124,"end":125},{"type":"T_SEMICOLON","context":"normal","value":";","line":4,"start":125,"end":126},{"type":"T_IDENTIFIER","context":"normal","value":"render","line":6,"start":130,"end":136},{"type":"T_LPAREN","context":"normal","value":"(","line":6,"start":136,"end":137},{"type":"T_RPAREN","context":"normal","value":")","line":6,"start":137,"end":138},{"type":"T_LCURLY","context":"normal","value":"{","line":6,"start":139,"end":140},{"type":"T_RETURN","context":"normal","value":"return","line":7,"start":145,"end":151},{"type":"T_THIS","context":"normal","value":"this","line":7,"start":152,"end":156},{"type":"T_PERIOD","context":"normal","value":".","line":7,"start":156,"end":157},{"type":"T_IDENTIFIER","context":"normal","value":"props","line":7,"start":157,"end":162},{"type":"T_PERIOD","context":"normal","value":".","line":7,"start":162,"end":163},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":7,"start":163,"end":166},{"type":"T_SEMICOLON","context":"normal","value":";","line":7,"start":166,"end":167},{"type":"T_RCURLY","context":"normal","value":"}","line":8,"start":170,"end":171},{"type":"T_RCURLY","context":"normal","value":"}","line":9,"start":172,"end":173},{"type":"Line","context":"comment","value":"// `React.ElementProps<>` requires `foo` even though it has a `defaultProp`.","line":11,"start":175,"end":251},{"type":"T_LPAREN","context":"normal","value":"(","line":12,"start":252,"end":253},{"type":"T_LCURLY","context":"normal","value":"{","line":12,"start":253,"end":254},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":12,"start":254,"end":257},{"type":"T_COLON","context":"normal","value":":","line":12,"start":257,"end":258},{"type":"T_NUMBER","context":"normal","value":"42","line":12,"start":259,"end":261},{"type":"T_RCURLY","context":"normal","value":"}","line":12,"start":261,"end":262},{"type":"T_COLON","context":"type","value":":","line":12,"start":262,"end":263},{"type":"T_IDENTIFIER","context":"type","value":"React","line":12,"start":264,"end":269},{"type":"T_PERIOD","context":"type","value":".","line":12,"start":269,"end":270},{"type":"T_IDENTIFIER","context":"type","value":"ElementProps","line":12,"start":270,"end":282},{"type":"T_LESS_THAN","context":"type","value":"<","line":12,"start":282,"end":283},{"type":"T_TYPEOF","context":"type","value":"typeof","line":12,"start":283,"end":289},{"type":"T_IDENTIFIER","context":"type","value":"MyComponent","line":12,"start":290,"end":301},{"type":"T_GREATER_THAN","context":"type","value":">","line":12,"start":301,"end":302},{"type":"T_RPAREN","context":"normal","value":")","line":12,"start":302,"end":303},{"type":"T_SEMICOLON","context":"normal","value":";","line":12,"start":303,"end":304},{"type":"Line","context":"comment","value":"// `React.ElementConfig<>` does not require `foo` since it has a `defaultProp`.","line":14,"start":306,"end":385},{"type":"T_LPAREN","context":"normal","value":"(","line":15,"start":386,"end":387},{"type":"T_LCURLY","context":"normal","value":"{","line":15,"start":387,"end":388},{"type":"T_RCURLY","context":"normal","value":"}","line":15,"start":388,"end":389},{"type":"T_COLON","context":"type","value":":","line":15,"start":389,"end":390},{"type":"T_IDENTIFIER","context":"type","value":"React","line":15,"start":391,"end":396},{"type":"T_PERIOD","context":"type","value":".","line":15,"start":396,"end":397},{"type":"T_IDENTIFIER","context":"type","value":"ElementConfig","line":15,"start":397,"end":410},{"type":"T_LESS_THAN","context":"type","value":"<","line":15,"start":410,"end":411},{"type":"T_TYPEOF","context":"type","value":"typeof","line":15,"start":411,"end":417},{"type":"T_IDENTIFIER","context":"type","value":"MyComponent","line":15,"start":418,"end":429},{"type":"T_GREATER_THAN","context":"type","value":">","line":15,"start":429,"end":430},{"type":"T_RPAREN","context":"normal","value":")","line":15,"start":430,"end":431},{"type":"T_SEMICOLON","context":"normal","value":";","line":15,"start":431,"end":432}],"errors":[]}
Like React.Element<typeof Component>
, typeof Component
must be the
type of a React component so you need to use typeof
as in
React.ElementProps<typeof MyComponent>
.
React.ElementRef<typeof Component>
Gets the instance type for a React element. The instance will be different for
various component types:
- React class components will be the class instance. So if you had
class Foo extends React.Component<{}> {}
and used
React.ElementRef<typeof Foo>
then the type would be the instance of Foo
.
- React stateless functional components do not have a backing instance and so
React.ElementRef<typeof Bar>
(when Bar
is function Bar() {}
) will give
you the undefined type.
- JSX intrinsics like
div
will give you their DOM instance. For
React.ElementRef<'div'>
that would be HTMLDivElement
. For
React.ElementRef<'input'>
that would be HTMLInputElement
.
Like React.Element<typeof Component>
, typeof Component
must be the
type of a React component so you need to use typeof
as in
React.ElementRef<typeof MyComponent>
.
React.Config<Props, DefaultProps>
Calculates a config object from props and default props. This is most useful for annotating
HOCs that are abstracted over configs. See our docs on writing HOCs for more information.