# react/prop-types

> Require every prop that a component uses to be declared

A prop that a component reads but doesn't declare is invisible to anyone who uses the component. Nothing says that it exists, what type it has, or that it was misspelled.

A prop counts as declared if it's in the component's `propTypes` or in the TypeScript type of its props.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"react/prop-types" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"react/prop-types" = ["error", {
  ignore = [], # list of strings
  customValidators = [], # list of strings
  skipUndeclared = false,
}]
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}
```jsx
function Greeting({ name }) {
  return <h1>Hello {name}</h1>;
}
```

{/* bad */}
```jsx
function Profile(props) {
  return <p>{props.name} ({props.age})</p>;
}

Profile.propTypes = {
  name: PropTypes.string.isRequired,
};
```

Not reported:

{/* good */}
```jsx
function Greeting({ name }) {
  return <h1>Hello {name}</h1>;
}

Greeting.propTypes = {
  name: PropTypes.string.isRequired,
};
```

{/* good */}
```tsx
type Props = { name: string };

function Greeting({ name }: Props) {
  return <h1>Hello {name}</h1>;
}
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `ignore` | `[]` | Prop names that are never reported. |
| `customValidators` | `[]` | Names of objects with your own validators, such as `Validators` in `Validators.shape()`. A prop declared with one of them accepts any nested property. |
| `skipUndeclared` | `false` | Skip components that don't declare any props. |

Not reported with `ignore: ["children"]`:

{/* good {"options": [{"ignore": ["children"]}]} */}
```jsx
function Card({ children }) {
  return <section>{children}</section>;
}
```

With `skipUndeclared`, the first component is skipped. The second one declares its props, so it's still checked:

{/* bad {"options": [{"skipUndeclared": true}], "count": 1} */}
```jsx
function Greeting({ name }) {
  return <h1>Hello {name}</h1>;
}

function Profile({ name, age }) {
  return <p>{name} ({age})</p>;
}

Profile.propTypes = {
  name: PropTypes.string.isRequired,
};
```

The rule checks a prop's properties against `shape()`. Here `user.name` isn't in the shape:

{/* bad */}
```jsx
function Profile({ user }) {
  return <p>{user.name}</p>;
}

Profile.propTypes = {
  user: Validators.shape({ id: PropTypes.number }),
};
```

Not reported with `customValidators: ["Validators"]`:

{/* good {"options": [{"customValidators": ["Validators"]}]} */}
```jsx
function Profile({ user }) {
  return <p>{user.name}</p>;
}

Profile.propTypes = {
  user: Validators.shape({ id: PropTypes.number }),
};
```

## When not to use it

React 19 ignores `propTypes`. In a TypeScript project the compiler already rejects a prop that isn't in the type, so this rule adds little there.
