Making ESLint Happy in Mixed TypeScript/Javascript Projects

Making ESLint Happy in Mixed TypeScript/Javascript Projects

I've become a huge fan of Linting over the last several years. Along with figuring out how to write to stdout for debugging and getting unit tests running, it is one of the first things I get set up when starting a new project or learning a new language. Combined with auto-fixing features like Prettier , it has really helped speed up my development process and cut down on the initial learning curve... not to mention cut down on bugs and typos.

Robert Cooper has a nice thorough post about Using ESLint and Prettier in a TypeScript Project including React and Prettier support. I use this setup and it has been working great.

I'm in the process of converting a component library wrapping Material-UI to TypeScript. One of the great things about TypeScript is that you can have Javascript code and TypeScript running together in the same codebase. However, I ran into an issue with the mixing of React linting rules between Javascript and TypeScript using the Robert Cooper's setup.

The ESLint Errors

Consider the following React component converted to TypeScript:

import React from 'react';

interface TestProps {
  foo: string;
  bar: Array<number>;
}

const Test: React.FunctionComponent<TestProps> = ({ foo, bar }) => {
  console.log(bar);
  return (
    <>
      <h3>{foo}</h3>
      <ul>
        {bar.map(i => (
          <li>{i}</li>
        ))}
      </ul>
    </>
  );
};
export default Test;

// Use like this:
// <Test foo="This is a Test" bar={[1111, 2222, 3333, 4444, 5555]} />

With the ESlint/TypeScript/Prettier setup outlined in the Robert Cooper post above, there are two types of errors:

Missing Props Validation PropTypes are a Non TypeScript way to impose some sanity in Javascript Components. I suggest using them if you are not using TypeScript. However, I am converting to TypeScript and don't want these errors clogging up the VSCode problems tab or preventing a build.

  • 'bar' is missing in props validation eslint(react/prop-types)
  • 'foo' is missing in props validation eslint(react/prop-types)

(Missing key prop I won't go into why this is a bad error to ignore, but you can learn more about iter keys here. In short, we want ESLint to catch these errors.

  • Missing "key" prop for element in iterator eslint(react/jsx-key)

The Conflicting ESLint Rules

The following are the important lines from the .eslintrc

...
  "extends": [
      "plugin:react/recommended", 
      "plugin:@typescript-eslint/recommended",
  ],
...

At first, I attempted to comment out plugin:react/recommended which prevented the react/prop-types error. However, this disabled all React specific linting and thus didn't error on the react/jsx-key.

Therefore, I found myself in a pickle. I didn't want to use PropTypes for TypeScript but I did want all the other React ESLint benefits for both TypeScript and regular Javascript.

ESLint Language Overrides to the Rescue:

ESLint 6 includes a lot of changes. One of which is better support for language specific overrides. Leveraging this, we can override our vendor recommended rules with TypeScript Specific ones.

Add this property to your .eslintrc:

"overrides": [
    {
        "files": ["**/*.tsx"],
        "rules": {
            "react/prop-types": "off"
        }
    }
]

Conclusion

Through the use of ESlint's override directives, we can define language specific linting rules and thus get rid of the PropType errors for TypeScript files while keeping all of the other recommended React rules for both Javascript and TypeScript.

This is my first time converting existing components React components to TypeScript. If you have a better solution or find a typo, point it out in the comments. Additionally, check out other programming articles at blainegarrett.com or follow me on twitter @blainegarrett.

Image Credit: Nili Fossae, layered bedrock as horizontal striations in the light toned sediments in the floor of a canyon near Syrtis Major. Original from NASA. Digitally enhanced by rawpixel by NASA is licensed under CC0 1.0