Flow: Provide a way to clever merge Props and defaultProps of an React Component

Created on 11 Sep 2017  路  6Comments  路  Source: facebook/flow

Code example:

// @flow
import * as React from 'react';

type Props = {
  foo: number, // foo is required.
  bar: 'bar' | 'baz', // bar is not required: it's in the defaultProps
};

class MyComponent extends React.Component<Props> {
  static defaultProps = {
    bar: 'bar',
  };
}

// all's fine
<MyComponent foo={42} />;

// but how to type an object that will be passed to MyComponent via spread?

// 1. Obviously wrong way: flow will not try to understand how we will use myCompProps
// const myCompProps: Props = { foo: 42 }; // - property `bar` missed

// 2. Less obviously wrong way
// const myCompProps: $PropertyType<MyComponent, 'props'> = { foo: 42 }; // - property `bar` missed

<MyComponent {...myCompProps} />;

You can try it

So, we need a convinient way to create a type based on Props and defaultProps. It should be exactly like Props, but all props from defaultProps should be marked as optional.

Most helpful comment

It works + we have React.ElementConfig now.

All 6 comments

I'm guessing this is the same issue, or at least similar:

// @flow
import * as React from 'react';

type Props = {
  foo: number, // foo is required.
  bar: 'bar' | 'baz', // bar is not required: it's in the defaultProps
};

class MyComponent extends React.Component<Props> {
  static defaultProps = {
    bar: 'bar',
  };
}

// all's fine
<MyComponent foo={42} />;

function getComponent(compProps: Props) {
  return <MyComponent {...compProps} />
}

getComponent({foo: 2})

try flow link: try it

What about this? Basic idea is taking a $Diff between the props and typeof the default props. I haven't kicked the tires thoroughly at all, but maybe it's a start.

@AndrewSouthpaw Unfortunately it's not a right way, too, because it makes components unsound

Hmm. How about combining $Diff and $Shape in an intersection?

Hmmm, looks good, I'll try to use it in real codebase and see if it works on more cases.

Thank you very much!

It works + we have React.ElementConfig now.

Was this page helpful?
0 / 5 - 0 ratings