In January 2019, TypeScirpt officially decided to fully adopt ESLint as a code checking tool and created a new project, typescript-ESLint, TypeScript file parser @typescript-eslint/parser and related configuration options @typescript-eslint/eslint-plugin are provided. Both previous lint solutions are deprecated:

  • Typescript-eslint-parser is no longer maintained
  • TSLint will provide a migration tool, And stop maintaining TSLint Once we consider esLint feature-complete W.R.T. TSLint, We will deprecate TSLint and help users migrate to ESLint1)

In summary, the current and future TypeScript code checking scheme is typescript-ESLint.

What is code review

Code inspection is mainly used to find code errors and unify the code style.

In JavaScript projects, we generally use ESLint for code checking, which greatly enriches the scope with its plug-in features and can even be used to check typescript code when paired with typescript-ESLint.

Why code review

One might think that JavaScript is very flexible and therefore requires code review. TypeScript already checks for a lot of problems at compile time, so why code check?

TypeScript focuses on type checking, not code style. When there are more and more people in the team, the same logic may be written differently by different people:

  • Should the indent be four Spaces or two Spaces?
  • Should it be disabled?var?
  • Whether the interface name should start withIAt the beginning?
  • Whether it should be mandatory= = =Rather than= =?

These are issues that TypeScript doesn’t care about, but affect the efficiency, understandability, and maintainability of collaborative development.

Here’s a concrete example:

var myName = 'Tom';

console.log(`My name is ${myNane}`);
console.log(`My name is ${myName.toStrng()}`);Copy the code

Can you see any errors in the above code?

When TSC is compiled and ESLint is checked, the following error message is reported:

let myName = 'Tom'; Eslint (no-var) console.log(' My name is ${myNane} '); // Unexpected var, use let or const int.eslint (no-var) console.log(' My name is ${myNane} '); // Cannot find name 'myNane'. Did you mean 'myName'? // ESLint reports an error message: // 'myNane' is not defined.esLint (no-undef) console.log(' My name is ${myName.tostrng ()} '); // Property 'toStrng' does not exist on type 'string'. Did you mean 'toString'?Copy the code
Existing problems tscWhether or not an error eslintWhether or not an error
You should useletconstRather thanvar
myNameIt was written by mistakemyNane
toStringIt was written by mistaketoStrng ✅ ️

In the above example, we used var to define a variable, but ES6 has the more advanced syntax let and const, which can be checked by ESLint to indicate that we should use let or const instead of var.

TSC and ESLint can check for undefined variables myNane.

Because ESLint does not know which methods exist for myName, it does not check for misspelled toString.

Thus, ESLint can find errors that TSC doesn’t care about and check for potential problems, so code checking is very important.

Use ESLint in TypeScript

Install ESLint

ESLint can be installed in the current project or in a global environment, and since code checking is an important part of the project, we would typically install it in the current project. You can run the following script to install:

npm install --save-dev eslintCopy the code

Since ESLint uses Espree for syntax parsing by default, some TypeScript syntax is not recognized. We need to install @typescript-esLint /parser instead of the default parser. Don’t forget to install TypeScript as well:

npm install --save-dev typescript @typescript-eslint/parserCopy the code

Next you need to install the corresponding @typescript-esLint /eslint-plugin, which supplements the ESLint default rules by providing additional rules for TS syntax.

npm install --save-dev @typescript-eslint/eslint-pluginCopy the code

Creating a Configuration File

ESLint needs a configuration file to determine which rules to check, typically named.eslintrc.js or.eslintrc.json.

When running ESLint to check a file, it will first try to read the configuration file in the directory in which the file is stored, then go up one level and combine the found configuration as the configuration of the file being checked.

We create.eslintrc.js in the root directory of our project with the following contents:

Module. exports = {parser: '@typescript-eslint/parser', plugins: ['@typescript-eslint'], rules: {// disable var' no-var': "Error ", // use interface instead of type '@typescript-eslint/consistent-type-definitions': ["error", "interface"]}}Copy the code

In the configuration above, we specified two rules, where no-var is a rule native to ESLint, @typescript-eslint/consistent-type-definitions is a new rule added to @typescript-eslint/eslint-plugin.

The value of a rule is usually an array (@typescript-eslint/consistent-type-definitions in the above example), where the first item is one of off, WARN, or error, indicating closure, warning, or error. The following items are other configurations of this rule.

If there is no other configuration, you can abbreviate the value of the rule to the first item in the array (no-var in the above example).

The meanings of close, warning and error are as follows:

  • Off: Disables this rule
  • Warning: An error message is printed during code checks, but exit code will not be affected
  • Error: When an error is found, not only will an error message be output, but the exit code will be set to 1.

Check a TS file

With the configuration file created, let’s create a TS file to see if we can check it with ESLint.

Create a new file named index.ts and copy the following into it:

var myName = 'Tom';

type Foo = {};Copy the code

Then execute the following command:

./node_modules/.bin/eslint index.tsCopy the code

The following error message is displayed:

/path/to/index.ts 1:1 error Unexpected var, use let or const instead no-var 3:6 error Use an `interface` instead of a `type` * * @typescript-eslint/consistent-type-definitions * 2 problems (2 errors, 0 warnings) 2 errors and 0 warnings potentially fixable with the `--fix` option.Copy the code

The preceding command output shows that the two rules have taken effect. Use interface in preference to type.

Note that we use./node_modules/.bin/eslint instead of the global ESLint script, because code checking is an important part of the project, so we would normally install it in the current project.

However, it is inconvenient to execute such a long script at a time. We can simplify this step by adding a script to package.json to create an NPM script:

{
    "scripts": {
        "eslint": "eslint index.ts"
    }
}Copy the code

Simply execute NPM run ESLint.

Review the TS files for the entire project

Our project source files are usually in the SRC directory, so we need to change the esLint script in package.json to check a directory instead. Since esLint does not check files with the.ts suffix by default, the argument — ext.ts is required:

{
    "scripts": {
        "eslint": "eslint src --ext .ts"
    }
}Copy the code

NPM run esLint checks all files with the.ts suffix in the SRC directory.

Integrate ESLint checking with VSCode

Integrating ESLint checking into the editor allows you to detect errors during development and even fix them automatically when you save, greatly increasing development efficiency.

To integrate ESLint checking with VSCode, you need to install the ESLint plugin, click the “extend” button, search for ESLint, and install it.

The ESLint plugin in VSCode does not check the.ts suffix by default, you need to add the following configuration in “File => Preferences => Settings => Workspace” (you can also create a configuration file in the project directory.vscode/settings.json) :

{
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "typescript"
    ],
    "typescript.tsdk": "node_modules/typescript/lib"
}Copy the code

Then open another.ts file and move the mouse pointer to the red prompt, you can see this error message:

We can also turn on auto-repair on save by configuring:

{
    "eslint.autoFixOnSave": true,
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        {
            "language": "typescript",
            "autoFix": true
        },
    ],
    "typescript.tsdk": "node_modules/typescript/lib"
}Copy the code

After saving the file, it can be automatically fixed as:

let myName = 'Tom';

interface Foo {}Copy the code

Use Prettier to fix formatting errors

ESLint includes checks for code formats such as Spaces, semicolons, and so on. But a more advanced tool for formatting code in the front-end community is Prettier.

Prettier focuses on formatting code, parsing it so that everyone writes the same way.

Install Prettier first:

npm install --save-dev prettierCopy the code

Then create a file prettier.config.js that contains the configuration items for Prettier. Prettier is rarely used, so I recommend a configuration rule for Prettier:

// prettier.config.js or.prettierrc.js module.exports = {printWidth: 100, // Use 4 space to indent_tabWidth: {// prettier.config.js or.prettierrc.js module.exports = {// a line of printWidth: 100, // use 4 space to indent_tabWidth: // Use semicolons at the end of the line, // Use singleQuote: true, // Use quotation marks for the key of the object only when necessary: 'as-needed', // JSX uses double quotes instead of single quotes, // trailingComma: 'None ', // braces need spacing at the beginning and end of bracketSpacing: true, // JSX tag Angle brackets need newline jsxBracketSameLine: False, // arrowParens: 'always', // Each file is formatted to the full contents of the file rangeStart: 0, rangeEnd: // @prettier requirePragma: false does not automatically insert @prettier insertPragma: False, / / use the default fold line standard proseWrap: 'preserve, / / according to display style decided to don't fold line htmlWhitespaceSensitivity HTML: 'CSS ', // use lf endOfLine: 'lf'};Copy the code

Next, install the Prettier plugin in VSCode and modify.vscode/settings.json:

{
    "files.eol": "\n",
    "editor.tabSize": 4,
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "eslint.autoFixOnSave": true,
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        {
            "language": "typescript",
            "autoFix": true
        }
    ],
    "typescript.tsdk": "node_modules/typescript/lib"
}Copy the code

This implements automatic formatting when saving files and automatically fixes ESLint errors.

Note that because ESLint can also check for formatting problems, when used with Prettier, we usually disable formatting rules in ESLint otherwise there would be conflicts.

ESLint configuration using AlloyTeam

There are too many ESLint native rules and @typescript-eslint/eslint-plugin rules, and some of the native rules don’t support typescript well and need to be disabled.

Here I recommend using the TypeScript version of the AlloyTeam ESLint rule, which already provides a complete set of configuration rules and is completely compatible with Prettier (eslint-config-alloy does not contain any code format rules, Coding formatting is left to Prettier, a more professional Prettier.

Installation:

npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-alloyCopy the code

Create.eslintrc.js in your project root directory and copy the following contents into the file:

module.exports = { extends: [ 'alloy', 'alloy/typescript', ], env: {// Your environment variables (including several predefined global variables) // Your environments (which contains several predefined global variables) // // browser: true, // node: true, // mocha: true, // jest: true, // jquery: true }, globals: {// Your global variables (setting to false means it's not allowed to be reassigned) // Your global variables (setting to false means it's not allowed to be reassigned) // // myGlobal: false}, rules: {// Customize your rules}};Copy the code

For more information, refer to the AlloyTeam ESLint rule

Use ESLint to check TSX files

If you want to support TSX file checking as well, you need to make some adjustments to the steps above:

The installationeslint-plugin-react

npm install --save-dev eslint-plugin-reactCopy the code

Added to scripts.eslint in package.json.tsxThe suffix

{
    "scripts": {
        "eslint": "eslint src --ext .ts,.tsx"
    }
}Copy the code

New typescriptreact check in VSCode configuration

{
    "files.eol": "\n",
    "editor.tabSize": 4,
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "eslint.autoFixOnSave": true,
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        {
            "language": "typescript",
            "autoFix": true
        },
        {
            "language": "typescriptreact",
            "autoFix": true
        }
    ],
    "typescript.tsdk": "node_modules/typescript/lib"
}Copy the code

Use the React version of TypeScript in the AlloyTeam ESLint rule

AlloyTeam TypeScript React version of the ESLint rule

Troubleshootings

Cannot find module ‘@typescript-eslint/parser’

You are running global ESLint, you need to run./node_modules/.bin/eslint instead.

VSCode does not display ESLint errors

  1. Check whether files => Preferences => Settings are correctly configured
  2. Check that the necessary NPM packages are installed
  3. check.eslintrc.jsIs it configured?
  4. Check if the file is in.eslintignore

If all else fails, you can configure “eslint.trace.server”: “Messages” in “Files => Preferences => Settings”, press Ctrl+Shift+U to open the output panel, then select ESLint Output to see the error.

Why do some defined variables (such as useenumESLint does not report an error when a defined variable) is not used?

This type of checking of variable definitions is not supported. It is recommended to add the following configuration to tsconfig.json to enable the TSC compilation process to check that unused variables are defined:

{
    "compilerOptions": {
        "noUnusedLocals": true,
        "noUnusedParameters": true
    }
}Copy the code

With noUnusedParameters enabled, only the second parameter is used, but the first parameter must be passed in, which results in an error

The first parameter can start with an underscore, see github.com/Microsoft/T…


  • Chapter one: Engineering
  • Next chapter: Compile options