Search code examples
typescripteslinttypescript-eslinttypescript-class

Resolve "@typescript-eslint/no-invalid-this" issue for class fields without conflicting with "@typescript-eslint/no-this-alias"


In below code:

import { Vue, Component } from "vue-property-decorator";  


@Component({
  components: {}
})
export default class ProductViewingAndEditingPage extends Vue {

  private readonly componentsReferencesIDs: {
    productTitleInputField: string;
    productPriceInputControl: string;
  } = {
    productTitleInputField: "ProductTitle--InputField",
    productPriceInputControl: "ProductPrice--InputComponent"
  };

  private readonly productDataFormValidator: InputsGroupValidator = new InputsGroupValidator({
    controls: {
      [this.componentsReferencesIDs.productTitleInputField]:
          this.$refs[this.componentsReferencesIDs.productTitleInputField],
      [this.componentsReferencesIDs.productPriceInputControl]:
          this.$refs[this.componentsReferencesIDs.productPriceInputControl]
    }
  });
}

@typescript/eslint emits @typescript-eslint/no-invalid-this issue (because it's not ESLint's no-invalid-this, this rule understands the class fields.).

Musings about conceptual solution

If I make componentsReferencesIDs to static class field, it's become impossible to retrieve the values from vue template.

Arrow functions could not be used here because here is class field. And also, if we alias this, we will face with no-this-alias rule.

I understand that ESLint is not the sole source of truth. But I want the justification like "because 〈argument〉, this ESLint rule does not cover this case."


Solution

  • This is now working correctly in ESLint - just need to update your ESLint core and @typescript-eslint versions. playground example


    Previous, outdated answer for posperity:

    @typescript-eslint/no-invalid-this just hasn't had support for this in class properties added.

    The extension rule was only added to the project relatively recently. At the time, the author worked on the feature they needed, which was support for this args.

    As a community maintained project, we rely upon support from the community to help us add rules, add features and fix bugs.
    If anyone wants to tackle this - please feel free to submit a PR - I believe that it should actually be a relatively simple fix.

    Relevant issue on github: https://github.com/typescript-eslint/typescript-eslint/issues/491


    As an aside, this probably begs the question "why hasn't this been fixed in over a year!?"

    Two reasons:

    1. When you have the noImplicitThis compiler option turned on, TypeScript itself will throw a compiler error if you're using an invalid this.Because it's handled by TS directly, the vast majority of users don't feel the need to duplicate the error with a lint rule.
    2. Not many users use this in class properties, meaning users aren't likely to run into this issue to begin with. Some users don't like that style of properties, but I believe most users don't actually know that it's valid to do this.

    Putting these two together - few users use the lint rule, and fewer users still use this in class properties - so there hasn't been enough people to motivate the community to fix it.