Skip to content

[no-unused-vars] False positive because React JSXIdentifier nodes are ignored #868

Closed
@octogonz

Description

@octogonz

Repro

{
  "rules": {
    "@typescript-eslint/no-unused-vars": [ "error" ]
  }
}
import * as React from 'react';

// ERROR: 'Foo' is defined but never used. [Error/@typescript-eslint/no-unused-vars]
class Foo extends React.Component { }

export class Bar extends React.Component {
  public render(): React.ReactNode {
    return <Foo />
  }
}

Expected Result

There should be no error for Foo, because it is used in the expression <Foo />.

Actual Result

The error is reported.

Additional Info

In the AST, the reference appears inside a JSXIdentifier node like this:

{
  "type": "ReturnStatement",
  "argument": {
	"type": "JSXElement",
	"openingElement": {
	  "type": "JSXOpeningElement",
	  "typeParameters": null,
	  "selfClosing": true,
	  "name": {
		"type": "JSXIdentifier",  // <====
		"name": "Foo"
	  },
	  "attributes": []
	},
	"closingElement": null,
	"children": []
  }
}

Whereas the rule only considers regular Identifier nodes:

return Object.assign({}, rules, {
'TSTypeReference Identifier'(node: TSESTree.Identifier) {
context.markVariableAsUsed(node.name);
},
TSInterfaceHeritage(node: TSESTree.TSInterfaceHeritage) {
if (node.expression) {
markHeritageAsUsed(node.expression);
}
},
TSClassImplements(node: TSESTree.TSClassImplements) {
if (node.expression) {
markHeritageAsUsed(node.expression);
}
},
'TSParameterProperty Identifier'(node: TSESTree.Identifier) {
// just assume parameter properties are used
context.markVariableAsUsed(node.name);
},
'TSEnumMember Identifier'(node: TSESTree.Identifier) {
context.markVariableAsUsed(node.name);
},
'*[declare=true] Identifier'(node: TSESTree.Identifier) {
context.markVariableAsUsed(node.name);
const scope = context.getScope();
const { variableScope } = scope;
if (variableScope !== scope) {
const superVar = variableScope.set.get(node.name);
if (superVar) {
superVar.eslintUsed = true;
}
}

Versions

package version
@typescript-eslint/eslint-plugin 2.0.0
@typescript-eslint/parser 2.0.0
TypeScript 3.5.2
ESLint 6.1.0
node 8.15.0
npm 6.4.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    package: eslint-pluginIssues related to @typescript-eslint/eslint-plugintriageWaiting for team members to take a look

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions