Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document that rules dealing with prop types recognize static types, too #2546

Merged
merged 1 commit into from
May 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions docs/rules/boolean-prop-naming.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Allows you to enforce a consistent naming pattern for props which expect a boolean value.

> **Note**: You can provide types in runtime types using [PropTypes] and/or
statically using [TypeScript] or [Flow]. This rule will validate your prop types
regardless of how you define them.

## Rule Details

The following patterns are considered warnings:
Expand All @@ -15,6 +19,13 @@ var Hello = createReactClass({
});
```

```jsx
type Props = {
enabled: boolean
}
const Hello = (props: Props) => <div />;
```

The following patterns are **not** considered warnings:

```jsx
Expand All @@ -25,16 +36,22 @@ var Hello = createReactClass({
render: function() { return <div />; };
});
```
```jsx
type Props = {
isEnabled: boolean
}
const Hello = (props: Props) => <div />
```

## Rule Options

```js
...
"react/boolean-prop-naming": [<enabled>, {
"propTypeNames": Array<string>,
"rule": <string>,
"message": <string>,
"validateNested": <boolean>
"react/boolean-prop-naming": [<enabled>, {
"propTypeNames": Array<string>,
"rule": <string>,
"message": <string>,
"validateNested": <boolean>
}]
...
```
Expand Down Expand Up @@ -99,3 +116,7 @@ This value is boolean. It tells if nested props should be validated as well. By
```jsx
"react/boolean-prop-naming": ["error", { "validateNested": true }]
```

[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html
[TypeScript]: http://www.typescriptlang.org/
[Flow]: https://flow.org/
18 changes: 13 additions & 5 deletions docs/rules/default-props-match-prop-types.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# Enforce all defaultProps have a corresponding non-required PropType (react/default-props-match-prop-types)

This rule aims to ensure that any `defaultProp` has a non-required `PropType` declaration.
This rule aims to ensure that any prop in `defaultProps` has a non-required type
definition.

Having `defaultProps` for non-existent `propTypes` is likely the result of errors in refactoring
or a sign of a missing `propType`. Having a `defaultProp` for a required property similarly
indicates a possible refactoring problem.
> **Note**: You can provide types in runtime types using [PropTypes] and/or
statically using [TypeScript] or [Flow]. This rule will validate your prop types
regardless of how you define them.

Having `defaultProps` for non-existent prop types is likely the result of errors
in refactoring or a sign of a missing prop type. Having a `defaultProp` for a
required property similarly indicates a possible refactoring problem.

## Rule Details

Expand Down Expand Up @@ -160,7 +165,7 @@ NotAComponent.propTypes = {

### `allowRequiredDefaults`

When `true` the rule will ignore `defaultProps` for `isRequired` `propTypes`.
When `true` the rule will ignore `defaultProps` for required prop types.

The following patterns are considered okay and do not cause warnings:

Expand Down Expand Up @@ -190,3 +195,6 @@ If you don't care about stray `defaultsProps` in your components, you can disabl
# Resources
- [Official React documentation on defaultProps](https://facebook.github.io/react/docs/typechecking-with-proptypes.html#default-prop-values)

[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html
[TypeScript]: http://www.typescriptlang.org/
[Flow]: https://flow.org/
24 changes: 16 additions & 8 deletions docs/rules/no-unused-prop-types.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Prevent definitions of unused propTypes (react/no-unused-prop-types)

Warns if a propType isn't being used.
Warns if a prop with a defined type isn't being used.

> **Note**: You can provide types in runtime types using [PropTypes] and/or
statically using [TypeScript] or [Flow]. This rule will validate your prop types
regardless of how you define them.

## Rule Details

Expand All @@ -19,17 +23,17 @@ Hello.propTypes = {
```

```jsx
class Hello extends React.Component {
type Props = {
firstname: string,
middlename: string, // middlename is never used above
lastname: string
}

class Hello extends React.Component<Props> {
render() {
return <div>Hello {this.props.firstname} {this.props.lastname}</div>;
}
}

Hello.propTypes: {
firstname: PropTypes.string.isRequired,
middlename: PropTypes.string.isRequired, // middlename is never used above
lastname: PropTypes.string.isRequired
},
```

The following patterns are **not** considered warnings:
Expand Down Expand Up @@ -114,3 +118,7 @@ AComponent.propTypes = {
bProp: PropTypes.string
};
```

[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html
[TypeScript]: http://www.typescriptlang.org/
[Flow]: https://flow.org/
102 changes: 64 additions & 38 deletions docs/rules/prop-types.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,66 @@
# Prevent missing props validation in a React component definition (react/prop-types)

PropTypes improve the reusability of your component by validating the received data.
Defining types for component props improves reusability of your components by
validating received data. It can warn other developers if they make a mistake while reusing the component with improper data type.

It can warn other developers if they make a mistake while reusing the component with improper data type.
> **Note**: You can provide types in runtime types using [PropTypes] and/or
statically using [TypeScript] or [Flow]. This rule will validate your prop types
regardless of how you define them.

## Rule Details

The following patterns are considered warnings:

```jsx
var Hello = createReactClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
function Hello({ name }) {
return <div>Hello {name}</div>;
// 'name' is missing in props validation
}

var Hello = createReactClass({
propTypes: {
firstname: PropTypes.string.isRequired
},
render: function() {
return <div>Hello {this.props.firstname} {this.props.lastname}</div>; // lastname type is not defined in propTypes
return <div>Hello {this.props.firstname} {this.props.lastname}</div>;
// 'lastname' type is missing in props validation
}
});

function Hello({ name }) {
// Or in ES6
class Hello extends React.Component {
render() {
return <div>Hello {this.props.firstname} {this.props.lastname}</div>;
// 'lastname' type is missing in props validation
}
}
Hello.propTypes = {
firstname: PropTypes.string.isRequired
}
```

In TypeScript:

```tsx
interface Props = {
age: number
}
function Hello({ name }: Props) {
return <div>Hello {name}</div>;
// 'name' type is missing in props validation
Copy link
Contributor

@golopot golopot Jan 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this and it seems that currently rule prop-types does not report on props with typescript type annotation, can you confirm or refute this?

Off topic: In my opinion rule prop-types should not report on props with ts/flow type annotation, since type-checker already excelled in pointing out usage of undeclared properties and that eslint-plugin-react also reporting the same thing just adds noise.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only think you're right if the propType exactly matches the type annotation - and since propTypes are more powerful than static types in many ways, this will often not be the case.

}
```

Examples of correct usage without warnings:

```jsx
function Hello({ name }) {
return <div>Hello {name}</div>;
}
Hello.propTypes = {
name: PropTypes.string.isRequired
}

var Hello = createReactClass({
propTypes: {
name: PropTypes.string.isRequired,
Expand Down Expand Up @@ -62,38 +91,31 @@ class HelloEs6WithPublicClassField extends React.Component {
}
```

The following patterns are **not** considered warnings:
In Flow:

```jsx
var Hello = createReactClass({
render: function() {
return <div>Hello World</div>;
}
});

var Hello = createReactClass({
propTypes: {
name: PropTypes.string.isRequired
},
render: function() {
```tsx
type Props = {
name: string
}
class Hello extends React.Component<Props> {
render() {
return <div>Hello {this.props.name}</div>;
}
});
}
```

// Referencing an external object disable the rule for the component
var Hello = createReactClass({
propTypes: myPropTypes,
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
The following patterns are **not** considered warnings:

```jsx
function Hello() {
return <div>Hello World</div>;
}

// Referencing an external object disable the rule for the component
function Hello({ name }) {
return <div>Hello {name}</div>;
}
Hello.propTypes = {
name: PropTypes.string.isRequired,
};
Hello.propTypes = myPropTypes;
```

## Rule Options
Expand Down Expand Up @@ -121,11 +143,11 @@ As it aptly noticed in

> Why should children be an exception?
> Most components don't need `this.props.children`, so that makes it extra important
to document `children` in the propTypes.
to document `children` in the prop types.

Generally, you should use `PropTypes.node` for `children`. It accepts
anything that can be rendered: numbers, strings, elements or an array containing
these types.
Generally, you should use `PropTypes.node` or static type `React.Node` for
`children`. It accepts anything that can be rendered: numbers, strings, elements
or an array containing these types.

Since 2.0.0 children is no longer ignored for props validation.

Expand All @@ -135,6 +157,10 @@ For this rule to work we need to detect React components, this could be very har

For now we should detect components created with:

* a function that return JSX or the result of a `React.createElement` call.
* `createReactClass()`
* an ES6 class that inherit from `React.Component` or `Component`
* a stateless function that return JSX or the result of a `React.createElement` call.

[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html
[TypeScript]: http://www.typescriptlang.org/
[Flow]: https://flow.org/
19 changes: 16 additions & 3 deletions docs/rules/require-default-props.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# Enforce a defaultProps definition for every prop that is not a required prop (react/require-default-props)

This rule aims to ensure that any non-required `PropType` declaration of a component has a corresponding `defaultProps` value.
This rule aims to ensure that any non-required prop types of a component has a
corresponding `defaultProps` value.

One advantage of `defaultProps` over custom default logic in your code is that `defaultProps` are resolved by React before the `PropTypes` typechecking happens, so typechecking will also apply to your `defaultProps`.
The same also holds true for stateless functional components: default function parameters do not behave the same as `defaultProps` and thus using `defaultProps` is still preferred.
> **Note**: You can provide types in runtime types using [PropTypes] and/or
statically using [TypeScript] or [Flow]. This rule will validate your prop types
regardless of how you define them.

One advantage of `defaultProps` over custom default logic in your code is that
`defaultProps` are resolved by React before the `PropTypes` typechecking
happens, so typechecking will also apply to your `defaultProps`. The same also
holds true for stateless functional components: default function parameters do
not behave the same as `defaultProps` and thus using `defaultProps` is still
preferred.

To illustrate, consider the following example:

Expand Down Expand Up @@ -337,3 +346,7 @@ If you don't care about using `defaultsProps` for your component's props that ar

# Resources
- [Official React documentation on defaultProps](https://facebook.github.io/react/docs/typechecking-with-proptypes.html#default-prop-values)

[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html
[TypeScript]: http://www.typescriptlang.org/
[Flow]: https://flow.org/
38 changes: 21 additions & 17 deletions docs/rules/sort-prop-types.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Enforce propTypes declarations alphabetical sorting (react/sort-prop-types)

Some developers prefer to sort propTypes declarations alphabetically to be able to find necessary declaration easier at the later time. Others feel that it adds complexity and becomes burden to maintain.
Some developers prefer to sort prop type declaratioms alphabetically to be able to find necessary declaration easier at the later time. Others feel that it adds complexity and becomes burden to maintain.

## Rule Details

Expand All @@ -17,16 +17,18 @@ var Component = createReactClass({
},
...
});

class Component extends React.Component {
```
```jsx
type Props = {
z: number,
a: any,
b: string
}
class Component extends React.Component<Props> {
...
}
Component.propTypes = {
z: PropTypes.number,
a: PropTypes.any,
b: PropTypes.string
};

```
```jsx
class Component extends React.Component {
static propTypes = {
z: PropTypes.any,
Expand All @@ -50,16 +52,18 @@ var Component = createReactClass({
},
...
});

class Component extends React.Component {
```
```jsx
type Props = {
a: string,
b: any,
c: string,
}
class Component extends React.Component<Props> {
...
}
Component.propTypes = {
a: PropTypes.string,
b: PropTypes.any,
c: PropTypes.string
};

```
```jsx
class Component extends React.Component {
static propTypes = {
a: PropTypes.any,
Expand Down