react/sort-prop-types

Require the keys of `propTypes` to be sorted alphabetically

In a long propTypes object, a fixed order makes props quick to find and duplicates easy to spot.

Capital letters sort before lowercase ones. After a spread, sorting starts over.

--fix sorts the keys.

Configure#

Off by default. To turn it on:

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

Every option, set to its default:

bunfig.toml
[lint.rules]
"react/sort-prop-types" = ["error", {
  ignoreCase = false,
  requiredFirst = false,
  callbacksLast = false,
  noSortAlphabetically = false,
  sortShapeProp = false,
  checkTypes = false,
}]

Examples#

Reported:

function Button({ label, size }) {
  return <button className={size}>{label}</button>;
}

Button.propTypes = {
  size: PropTypes.string,
  label: PropTypes.string,
};

Not reported:

function Button({ label, size }) {
  return <button className={size}>{label}</button>;
}

Button.propTypes = {
  label: PropTypes.string,
  size: PropTypes.string,
};

Options#

OptionDefaultWhat it does
ignoreCasefalseIgnore case when comparing the keys.
requiredFirstfalseRequire props marked .isRequired to come before the others.
callbacksLastfalseRequire props named like onChange to come after the others.
noSortAlphabeticallyfalseDon't check the alphabetical order. Use it with requiredFirst or callbacksLast.
sortShapePropfalseAlso check the keys inside PropTypes.shape({ ... }).
checkTypesfalseAlso check the props type of a function component, written inline or as a type alias. An interface isn't checked.

With requiredFirst and callbacksLast, each group is sorted alphabetically on its own:

Button.propTypes = {
  size: PropTypes.string.isRequired,
  label: PropTypes.string,
  theme: PropTypes.string,
  onClick: PropTypes.func,
};

With requiredFirst, this is reported, because size is required:

Button.propTypes = {
  label: PropTypes.string,
  size: PropTypes.string.isRequired,
};

With callbacksLast, this is reported, because onClick isn't last:

Button.propTypes = {
  label: PropTypes.string,
  onClick: PropTypes.func,
  size: PropTypes.string,
};

With noSortAlphabetically, only the groups matter:

Button.propTypes = {
  size: PropTypes.string,
  label: PropTypes.string,
  onClick: PropTypes.func,
};

With sortShapeProp, this is reported:

Profile.propTypes = {
  user: PropTypes.shape({
    name: PropTypes.string,
    email: PropTypes.string,
  }),
};

With checkTypes, this is reported:

type ButtonProps = {
  size: string;
  label: string;
};

function Button(props: ButtonProps) {
  return <button className={props.size}>{props.label}</button>;
}