palantir / tslint-react

:orange_book: Lint rules related to React & JSX for TSLint.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

New rule: require explicitly typed `defaultProps`

andrewbranch opened this issue · comments

It's easy write a component with unsafe defaultProps:

interface MyComponentProps {
  onClick?: React.MouseEventHandler<HTMLElement>;
}

class MyComponent extends React.Component<MyComponentProps> {
  static defaultProps = {
    onClick: 42
  };

  render() {
    return <div onClick={this.props.onClick} />;
  }
}

So it's useful to enforce declaring an explicit type for static defaultProps (which should basically always be Partial<P> where P is the type of the component’s props), which would catch such silly mistakes:

interface MyComponentProps {
  onClick?: React.MouseEventHandler<HTMLElement>;
}

class MyComponent extends React.Component<MyComponentProps> {
  static defaultProps: Partial<MyComponentProps> = {
  //     ^^^^^^^^^^^^ Type { onClick: number } is not convertible to Partial<MyComponentProps> or some error message along these lines
    onClick: 42
  };
}

I think it would be useful and would be happy to accept a PR!

I think to do this right, we’d need to use the type checker (ts.createProgram) to tell whether or not a class declaring defaultProps is in fact a React component. However, I'm not sure what the overhead for that is, and if it would be worth it just to check the AST for the text React.Component and maybe Component, also checking that Component is being imported from 'react' at some point (presumably faster but not as accurate). What are your feelings on it?

Actually, in TypeScript 3.0, you don’t want to explicitly type defaultProps. So, maybe instead of requiring an explicit type, a rule that checks that the inferred type of defaultProps is assignable to the class’s props interface would be valuable—which would definitely require the type checker.

Also see this discussion (which unfortunately currently seems to be on hold): DefinitelyTyped/DefinitelyTyped#28515

a rule that checks that the inferred type of defaultProps is assignable to the class’s props interface

this sounds like a good idea, but it should now be an eslint rule. see #210