Skip to content

[@typescript-eslint/no-unnecessary-type-assertion] Fixing Vue single file components applies changes to incorrect character location #4723

@jaa134

Description

@jaa134

Applying the automatic fix for non-null assertions removes a character from the wrong place. It seems related to #2591 and #2680 where vue-eslint-parser alters the locations information for every node it produces within a script tag, but it doesn't know about the typescript nodes, so their range information is wrong. The fix is being applied as if there was no script tag. You can see that by running the lint command without the --fix flag, the eslint command output reports the error at an incorrect line or character index.

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have read the FAQ and my problem is not listed.

Repro

Steps:

  1. Create a simple Vue 3 single file component like below. This component unnecessarily does type assertion on the string literal.
<script setup lang="ts">
  const test = 'foobar'.length!
</script>
<template>
  <div></div>
<template>
  1. Apply linting with --fix flag and with the rule enabled. See package.json/.eslintrc examples below. I am using latest versions of vue-eslint-plugin, this TS parser, this TS plugin, and Eslint.
  2. When linting completes, the letter "t" is removed from const and not the unnecessary non-null assertion.
module.exports = {
    env: {
        browser: true,
        es6: true,
        'vue/setup-compiler-macros': true
    },
    plugins: ['@typescript-eslint'],
    parser: 'vue-eslint-parser',
    parserOptions: {
        parser: '@typescript-eslint/parser',
        project: '**/tsconfig.json',
        sourceType: 'module',
        extraFileExtensions: ['.vue']
    },
    extends: [
        'eslint:recommended',
        'plugin:@typescript-eslint/recommended',
        'plugin:@typescript-eslint/recommended-requiring-type-checking',
        'plugin:vue/essential',
        'prettier'
    ],
    rules: {
        '@typescript-eslint/ban-types': 'off',
        '@typescript-eslint/no-namespace': 'off',
        '@typescript-eslint/adjacent-overload-signatures': 'off',
        '@typescript-eslint/prefer-regexp-exec': 'off',
        '@typescript-eslint/no-unsafe-call': 'off',
        '@typescript-eslint/no-unsafe-assignment': 'off',
        '@typescript-eslint/no-unsafe-member-access': 'off',
        '@typescript-eslint/no-unsafe-return': 'off',
        '@typescript-eslint/restrict-template-expressions': 'off'
    }
};
{
    "name": "foobar",
    "version": "0.0.1",
    "scripts": {
        "lint:js": "eslint src --ext .js,.ts,.vue --quiet",
        "lint:js:fix": "eslint src --ext .js,.ts,.vue --fix --quiet"
    },
    "dependencies": {
        "vue": "^3.2.25"
    },
    "devDependencies": {
        "@typescript-eslint/eslint-plugin": "^5.16.0",
        "@typescript-eslint/parser": "^5.16.0",
        "eslint": "^8.11.0",
        "eslint-config-prettier": "^8.3.0",
        "eslint-plugin-vue": "^8.5.0",
        "typescript": "^4.4.3",
        "vue-eslint-parser": "^8.3.0"
    }
}
{
  "compilerOptions": {
    "baseUrl": ".",
    "esModuleInterop": true,
    "jsx": "preserve",
    "lib": ["esnext", "dom"],
    "module": "esnext",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "paths": {
      "@/*": ["src/*"]
    },
    "resolveJsonModule": true,
    "sourceMap": true,
    "strict": true,
    "target": "esnext",
    "types": ["vite/client", "@types/jest"]
  },
  "include": ["src/**/*.ts", "src/**/*.vue"]
}

Expected Result

See that the non-null assertion was removed.

<script setup lang="ts">

  const test = 'foobar'.length

</script>

<template>
  <div >
<template>

Actual Result

See that the letter 't' was removed from const.

<script setup lang="ts">

  cons test = 'foobar'.length!

</script>

<template>
  <div >
<template>

Additional Info

It looks like a similar issue was identified in #2591. And a fix was applied in #2680.

Versions

package version
@typescript-eslint/eslint-plugin 5.16.0
@typescript-eslint/parser 5.16.0
TypeScript 4.4.3
ESLint 8.11.0
node 17.3.1

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinghas prthere is a PR raised to close thispackage: eslint-pluginIssues related to @typescript-eslint/eslint-pluginvueissues relating to vue support

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy