Search code examples
angulartypescripteslintprettiereslint-config-airbnb

Why does Prettier claim the `;` before destructuring assignment?


I have if block in my Angular component:

if (desc.length > 0) {
    [this.errorMsg] = desc
}

However, Prettier doesn't like it and recommends to put ; at the beginning of the destructuring assignment:

if (desc.length > 0) {
    ;[this.errorMsg] = desc
}

I just want to get why? Is there a bug in my ESLint or Prettier configuration? Or does it have reasons?

ADDED
.eslintrc.json:

{
  "overrides": [
    {
      "files": ["*.ts"],
      "parserOptions": {
        "project": [
          "tsconfig.*?.json",
          "e2e/tsconfig.e2e.json"
        ],
        "createDefaultProgram": true
      },
      "extends": [
        "plugin:@angular-eslint/recommended",
        // AirBnB guide style
        "airbnb-typescript/base",
        // Prettier settings
        "prettier",
        "plugin:prettier/recommended"
      ],
      "rules": {
        /**
         * Any TypeScript source code (NOT TEMPLATE) related rules you wish to use/reconfigure over and above the
         * recommended set provided by the @angular-eslint project would go here.
         */
        "@angular-eslint/directive-selector": [
          "error",
          { "type": "attribute", "prefix": "app", "style": "camelCase" }
        ],
        "@angular-eslint/component-selector": [
          "error",
          { "type": "element", "prefix": "app", "style": "kebab-case" }
        ]
      }
    },
    // NOTE: WE ARE NOT APPLYING PRETTIER IN THIS OVERRIDE, ONLY @ANGULAR-ESLINT/TEMPLATE
    {
      "files": ["*.html"],
      "extends": ["plugin:@angular-eslint/template/recommended"],
      "rules": {}
    },
    // NOTE: WE ARE NOT APPLYING @ANGULAR-ESLINT/TEMPLATE IN THIS OVERRIDE, ONLY PRETTIER
    {
      "files": ["*.html"],
      "excludedFiles": ["*inline-template-*.component.html"],
      "extends": ["plugin:prettier/recommended"],
      "rules": {
        // NOTE: WE ARE OVERRIDING THE DEFAULT CONFIG TO ALWAYS SET THE PARSER TO ANGULAR (SEE BELOW)
        "prettier/prettier": ["error", { "parser": "angular" }]
      }
    }
  ]
}

.prettierrc.json:

{
  "singleQuote": true,
  "tabWidth": 2,
  "printWidth": 120,
  "semi": false
}

Solution

  • Already got a bunch of discussion about this subject, if your interested to read the why

    The reason why the prettier add semi-colon at the start, even if it isn't strictly required, is that it makes it easier to move lines of code around the file without accidentally introducing ASI issues. - azz

    Edit: Prettier does also explain the reason why here

    But basically, it's because

    someCall()
    [a] = obj
    

    isn't the same as

    someCall();
    [a] = obj
    

    but since you ask prettier to remove the semi-colon, then it put it at the beggining

    someCall()
    ;[a] = obj
    

    You can also read the standardjs rules about the subject which says

    // ✓ ok
    ;[1, 2, 3].forEach(bar)
    
    // ✗ avoid
    [1, 2, 3].forEach(bar)