microsoft/tslint-microsoft-contrib

react-unused-props-and-state doesn't work with intersection types

karol-majewski opened this issue · 5 comments

Hello and thank you for your work. The issue I would like to report is related to react-unused-props-and-state rule. #311 allowed us to specify a regular expression used to recognize interfaces used to describe React Props and State.

The rule works perfectly when Props or State are defined within one interface. However, when using React together with Redux, it's a common practice to state your component's props as an intersection type:

// Passed by the parent.
interface OwnProps { /* ... */ }

// Passed by `mapStateToProps`.
interface ConnectedProps { /* ... */ }

// Passed by `mapDispatchToProps`.
interface ConnectedDispatch { /* ... */ }

type Props = OwnProps & ConnectedProps & ConnectedDispatch;

interface State { /* ... */ }

class MyComponent extends React.Component<Props, State> { /* ... */ }

Here, two interfaces (OwnProps and ConnectedProps) match the Props$ used in the rule configuration. In such scenario, the react-unused-props-and-state rule will report problems only for the last interface that matches the RegExp.

Example

interface OwnProps {
  p1: any; // No error (bad — OwnProps matches the RegExp)
}

interface ConnectedProps {
  p2: any; // Error (good — ConnectedProps matches the RegExp)
}

interface ConnectedDispatch {
  p3: any; // No error (good, ConnectedDispatch does not match the RegExp)
}

type Props = OwnProps & ConnectedProps & ConnectedDispatch;

interface State {
  s: any; // Error (good)
}

class SadComponent extends React.Component<Props, State> {
  render(): JSX.Element {
    return <span>:(</span>;
  }
}

Expected behavior

  • OwnProps should make TSLint report Unused React property defined in interface: p1 (react-unused-props-and-state)

Actual behavior

  • Only the last interface whose name matches the regular expression (here: ConnectedProps) is validated.

TSLint configuration

{
  "rulesDirectory": ["node_modules/tslint-microsoft-contrib"],
  "rules": {
    "react-unused-props-and-state": [
      true,
      {
        "state-interface-regex": "State$",
        "props-interface-regex": "Props$"
      }
    ]
  }
}

Usage

  • TSLint version: 5.9.1
  • TypeScript version: 2.7.1
  • Running TSLint via: CLI, Visual Studio Code

However, when using React together with Redux, it's a common practice to state your component's props as a union type:

Minor correction: this is an intersection type, not a union type.

Any progress? 🙄

@jose920405 none so far, sadly. This is accepting PRs so you & anybody are more than welcome to send a PR to fix this issue (please do!). If they do it'll be linked here.

💀 It's time! 💀

TSLint is being deprecated; therefore, it and tslint-microsoft-contrib are no longer accepting pull requests for major new changes or features. See palantir/tslint#4534. 😱

If you'd like to see this change implemented, you have two choices:

  • Recommended: Check if this is available in ESLint + typescript-eslint
  • Not Recommended: Fork TSLint or tslint-microsoft-contrib locally 🤷‍♂️

👋 It was a pleasure open sourcing with you!

If you believe this message was posted here in error, please comment so we can re-open the issue!