question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

The "react/default-props-match-prop-types" setting forces looser typing

See original GitHub issue

If you use the optional Flow Linter, you can get warnings for ‘sketchy’ checks, meaning when you do something like if (foo) or foo ? ... : ... when foo is not clearly typed. Example:

type Props = {
  isHappy?: boolean,
};

const Emoji = ({ isHappy }: Props) => 
  <span>{isHappy ? '😀' : '😭'}</span>;
//       ^^^^^^^  Sketchy null check on boolean which is potentially false. Perhaps you meant to check for null or undefined?

Emoji.defaultProps = {
  isHappy: false,
};

The linter thinks isHappy might be undefined, because we have annotated it as a maybe-boolean, but in fact it’s guaranteed to be boolean.

So in fact the Props definition above is wrong; it should just beisHappy: boolean, because the props argument passed into the function is guaranteed always to have a boolean isHappy value when you render via JSX, thanks to the defaultProps. The linter is not at fault here, we’re just confusing it by actively loosening the type for a prop that needn’t be loosened.

You can fix the linter warning by changing the Props to have isHappy: boolean. (And you can still then render <Emoji /> without type errors, thanks to the defaultProps.) But doing this breaks compatibility with this eslint-config-airbnb rule:

'react/default-props-match-prop-types': ['error', { allowRequiredDefaults: false }],

This ESLint rule seems, at first glance, to encourage stricter code. But it actually forces you to loosen Flow’s knowledge your props’ types. This causes Flow Linter warnings and may lead to real refinement problems down the line.

So I propose changing it to ['error', { allowRequiredDefaults: true }] to allow stricter props typing. The meaning of defaultProps is well established, and it needn’t be visually reinforced with corresponding maybe-types, especially if those maybe-types actually weaken Flow’s understanding of what’s going on.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:14

github_iconTop GitHub Comments

2reactions
ljharbcommented, Jun 29, 2018

That’s interesting. So it sounds like propTypes more closely match ElementConfig - where ElementProps are your internal props.

So, in that case, I’d say that the react plugin should be requiring ElementConfig, and not just “typed props” - and then all the same rules should apply. ElementProps is something that should be entirely optional.

2reactions
callumlockecommented, Jun 29, 2018

OK, you were calling it a bug until now. You may see it as a design flaw. But the fact is it works that way, and it’s intentional. Any tooling that claims to support Flow (like eslint-plugin-react) should support it based on how it actually works, or not at all.

FWIW, the React project seems to fully support Flow’s design here, and they export utility types that embrace the distinction: React.ElementConfig works out a component’s ‘config’ type (to match attributes in a JSX/React.createElement expression), while React.ElementProps gets you the type of the ‘props’ object passed into the function. These two types are treated and discussed as different things, in both the Flow docs and the React docs. It’s how things are and it’s not going to change. Personally I think it’s a useful distinction to make.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React Basis: Default Props and Typechecking with PropTypes.
In this blog we review two React fundamental topics including defaults props and typechecking with PropTypes. Props are objects passed from one ...
Read more >
How to set defaultProps for function? - Stack Overflow
We can define default values to props using the defaultProps property. defaultProps is used to ensure that props will have a value if...
Read more >
The React Handbook – Learn React for Beginners
Some tooling like ESLint have the ability to enforce defining the defaultProps for a Component with some propTypes not explicitly required. How ...
Read more >
ESLint-plugin-react: React-specific Linting Rules for ESLint
Enforce all defaultProps are defined and not "required" in propTypes. ... Prevent adjacent inline elements not separated by whitespace. ... Prevent passing of ......
Read more >
View Raw - UNPKG
import React from 'react'; interface InsertPositionsMap { after: InsertPosition; before: InsertPosition; } export const insertPositions: InsertPositionsMap; ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found