65

There is one problem with @typescript-eslint/no-unused-vars. So, we have type

type SomeType = (name: string) => void;

And we have @typescript-eslint/no-unused-vars error in string with type declaration, which says 'name' is defined but never used.

example of type usage:

export const LogSomeInfo: SomeType = (name: string) => {
    const a = name;
    console.log(a);
};

Or:

interface CheckboxPropsType {
    value: string,
    onClick(value: string): void
}

And eslint breaks at onClick... string, saying that value is defined but never used. Even if type assigned correctly and actual onClick handler uses the value!

Question: What's wrong with this rule and why it triggers in this case. Why eslint recognizes type declaration for functions in types/interfaces as regular function? It's problem with my eslint config?

"eslint": "^7.7.0", "@typescript-eslint/eslint-plugin": "^3.6.1", "@typescript-eslint/parser": "^4.0.1", "eslint-config-airbnb-typescript": "^9.0.0",

{
  "extends": [
    "airbnb-typescript",
    "airbnb/hooks",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 2018,
    "sourceType": "module",
    "project": "./tsconfig.json"
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  },
  "plugins": ["@typescript-eslint", "react-hooks", "react"],
  "env": {
    "browser": true
  },
  "rules": {
    "object-curly-newline": 0,
    "import/named": ["error"],
    "indent": ["error", 4],
    "react/jsx-indent": ["error", 4],
    "comma-dangle": ["error", "never"],
    "import/prefer-default-export": "off",
    "react/jsx-fragments": "off",
    "arrow-body-style": "off",
    "object-curly-spacing": "off",
    "@typescript-eslint/indent": ["error", 4, {"SwitchCase": 1}],
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "no-undef": "error",
    "react/jsx-indent-props": ["error", 4],
    "max-len": ["error", { "code": 120 }],
    "react/prop-types": "off"
  }
}

Aleksandr Solovey
  • 673
  • 1
  • 6
  • 4
  • 1
    why eslint-plugin 3.6.1 and parser 4.0.1? have you tried to update both to the same version (e.g. 4.0.1)? – Aprillion Sep 06 '20 at 18:27
  • 4
    Ran into a different issue with the same symptoms. We were using `no-unused-vars` instead of `@typescript-eslint/no-unused-vars`. Upgrading @typescript-eslint/eslint-plugin and @typescript-eslint/parser to 4.9.0 and adding the following to .eslintrc solved this problem: `"no-unused-vars": 0, "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }]` – Yves Dorfsman Dec 02 '20 at 17:21

4 Answers4

42

Source: I am the maintainer of the typescript-eslint project.

If you update your versions of @typescript-eslint/parser and @typescript-eslint/eslint-plugin to v4.1.0, you will be able to use the latest changes which make @typescript-eslint/no-unused-vars work properly for all cases.

Here's a typescript-eslint playground which shows the config and the examples working as intended.


As an aside - using v3.x of the plugin but v4.x of the parser will put you into a really weird state with undefined and unsupported behaviour.

You should make sure you are always using the same version of both packages, as each version is released together.

Brad Zacher
  • 2,915
  • 18
  • 31
  • 1
    Thanks. I was having the same issue, now it works after upgrading those 2 libs from 4.0.1 to 4.4.1. – mpoisot Oct 16 '20 at 20:08
  • 2
    This is the better solution today. Confirm working on 4.20.0 – Kevin Aung Mar 30 '21 at 15:12
  • 29
    I am on version `4.22.1` and am still getting the warnings. Is there any additional configurations required to disable linting on function parameters within `Types` or `Interfaces`? – Hansel May 06 '21 at 02:31
  • Out of curiosity, if both packages need to be used in the same version, why not combine them into a single package? Is there a reason for making them as two separate packages? – Alisson Reinaldo Silva Jun 20 '21 at 00:52
  • It provides a better config experience due to how ESLint does shorthands. You configure lint rules as `@typescript-eslint/` and the parser as `@typescript-eslint/parser`. If we merged them then we'd have to go with the `eslint-plugin` name (or else the rule config would be awful), so your parser would be `@typescript-eslint/eslint-plugin`; which is weird... Also the rules will mostly work with the babel parser, so there's not a hard requirement to use our parser. Also just nice from a codebase maintenance pov to keep the two different packages separate. So yeah - many reasons. – Brad Zacher Jun 20 '21 at 01:08
  • 5
    I have both on version `4.29.0` and I'm still facing this issue. – Conor Aug 24 '21 at 23:01
  • Seeing this issue on 4.6.1 – Garrett Sep 10 '21 at 20:38
  • 1
    @Garrett - update to the latest version. `4.6.1` is somewhere in the order of 10 months old – Brad Zacher Sep 10 '21 at 21:05
  • 2
    Still getting a false positive with `5.2.0` which is the current version as of this writing. I should also mention that I am using `@typescript-eslint/*` inside a Vue project. – praneetloke Oct 29 '21 at 02:13
  • Stackoverflow comments are not a good place to discuss or report bugs for obvious reasons. Please create a repro and file an issue on GitHub. – Brad Zacher Oct 29 '21 at 02:16
  • 1
    I'm confused, how is this still an issue 1 year after Brad's post? Also getting the false positive unused-vars warning today for a function type with both package versions being 5.4 – rails_has_elegance Nov 17 '21 at 09:38
  • 1
    I'm using 5.4.0 and this solution produces inconsistent results. It fixed properties getting flagged in interfaces, but now does not flag *actual* unused variables. It also still flags generic declarations like in interfaces and classes. I had to turn the entire feature off. – GHOST-34 Dec 08 '21 at 21:21
  • 7
    For people that are having issues and even downvoting my response - please file an issue on github with your config so I can help you - https://github.com/typescript-eslint/typescript-eslint. Downvoting / commenting with "it's not working" is pretty useless for getting your issue resolved. --- I'm not joking when I say that I want to help you resolve your issue. If it's a bug I'll fix it. If it's a config issue I'll help you correct it. Help me to help you by filing an GH issue with your code + config. – Brad Zacher Dec 09 '21 at 23:22
  • The rule is working properly for all cases we know of! Here are is our playground showing a few examples: https://typescript-eslint.io/play/#ts=4.5.2&sourceType=module&code=C4TwDgpgBAyg9gWwgFXNAvFAFAOwIZIBcUAzsAE4CWOA5gJRToB8UAbnJQCYDcAUBAA8wccsCgBjODjJQAYjmLwkqSI2z4ipCtXqMWGiH344ArgigBZEAFFT5gN5QAgmoCMUAL78hIsdWAQ5ABmeOLQAMIAFhDiANYARnACAArkcGAkKtD2vFB5bHgANiYQxFa2ZgB0TgA0uflS4YWUcVisRSXEZFS0dMTsXLxevP6BIWFQAHJwwACqJBCc7vZeoKrTcwucAExqK3wQdlMz84sAzFArQA&rules=N4IgAgLgngDgpgZwMYCcCWMIFpEBs0B2EA9AQPZYCuBlCcAJlgG4CGKCIAXCHCimShABfIA&tsConfig=N4XyA – Brad Zacher Dec 09 '21 at 23:24
  • @BradZacher your demo shows errors now in 6.2.1 – Cihad Turhan Aug 07 '23 at 14:25
  • @CihadTurhan Those errors are fully expected errors because they are unused things!!! – Brad Zacher Aug 09 '23 at 02:31
  • @BradZacher Now it works as it should – showing errors from eslint. When I tried, it gave errors related to installing dependencies. I guess it was temporary thing – Cihad Turhan Aug 21 '23 at 07:59
34

Similar question asked earlier check: Why ESLint throws 'no-unused-vars' for TypeScript interface?

Disable '@typescript-eslint/no-unused-vars': 0 rule and instead use "strict": true, "noUnusedLocals": true, and "noUnusedParameters": true, in tsconfig.json

chenrui
  • 8,910
  • 3
  • 33
  • 43
Dolly
  • 2,213
  • 16
  • 38
  • 1
    Yes. May be it's correct solution. You can disable this rule, and add to tsconfig --noUnusedLocals and --noUnusedParameters, or you can add @typescript-eslint/no-unused-vars-experimental to eslintrc. Both ways solve the problem – Aleksandr Solovey Sep 06 '20 at 19:03
  • 3
    `no-unused-vars-experimental` was experimental, and has since been deprecated. It will be removed in the next major - do not use it. Up to you if you want to use TS's built in unused checks or the eslint rule. The TS checks will block your build, so many people don't like them. See my answer below for how to fix your eslint config. – Brad Zacher Sep 08 '20 at 17:20
  • How will build get blocked? If you are fulfilling the strict rules – Dolly Sep 08 '20 at 17:31
  • TypeScript emits by default as long as the file is syntactically valid. `--noEmitOnError` is not the default. – Aluan Haddad Sep 08 '20 at 17:35
  • Agree! with @AluanHaddad – Dolly Sep 08 '20 at 17:35
  • 1
    Sure it's the default - but most user configs I've seen specifically reconfigure to not emit on error so they don't test on weird code that isn't correct. This is why so many users prefer _not_ to use the TS option - because it blocks their development. – Brad Zacher Sep 09 '20 at 19:34
6

Just make sure you have the latest version of the following:

  • typescript-eslint
  • @typescript-eslint/parser
  • @typescript-eslint/eslint-plugin

in your .eslintrc.js make sure you have the following lines added to rules section:

  "no-unused-vars": "off",
  "@typescript-eslint/no-unused-vars": ["error"]
basel juma
  • 1,987
  • 1
  • 10
  • 5
3

Another option to fix this is to add typescript-eslint to your extends and remove it from plugins:

extends: [
  `plugin:@typescript-eslint/recommended',
]

You can then also remove parser: @typescript-eslint/parser since by extending it, the plugin will handle all of this for you under the hood. You can still override some rules if needed:

  rules: {
    '@typescript-eslint/no-unused-vars': ['off'],
  },
Cathal Mac Donnacha
  • 1,285
  • 1
  • 16
  • 23