I am using TypeScript and Maquette to compile .tsx files. The code compiles correctly and runs in the browser, but ESLint is unhappy with my jsx
function, flagging it as an "unused var".
I tried to mimic the TypeScript Maquette starter project as closely as possible, but when I look at that project I don't see the linter warning. Somehow, in the starter project, ESLint and TypeScript recognize that jsx
is my factory function, but in my project, despite what seems to me to be identical configuration, it doesn't.
What's my missing piece of the puzzle? Despite reading all the docs several times and Googling this every way I could imagine, I haven't found anything that's identified the cause of the issue.
badge.tsx
import { jsx } from "maquette-jsx";
import { VNode } from "maquette";
import Component from "../../core/component";
export default class Badge extends Component {
init():void {}
renderVDom():VNode {
const {
gc,
state: { label },
} = this;
return (
<div key={this} class={gc("badge")} title={label}>
{ label }
</div>
);
}
}
But when I run eslint (./node_modules/.bin/eslint . --ext .json,.js,.ts,.jsx,.tsx
) I get the following warning:
.../js/components/badge/badge.tsx
1:10 warning 'jsx' is defined but never used @typescript-eslint/no-unused-vars
I'm including my config files below but it's a big project so I'm editing out the parts I feel aren't relevant:
package.json
{
"name": "...",
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.25.0",
"@typescript-eslint/parser": "^4.25.0",
"eslint": "7.7.x",
"maquette-jsx": "^3.0.1",
"ts-loader": "^8.3.0",
"typescript": "^4.2.4"
},
"dependencies": {
"maquette": "^3.5.0"
}
}
tsconfig.json
{
"include": [
"./js/**/*.ts",
"./js/**/*.tsx"
],
"compilerOptions": {
"jsx": "react",
"jsxFactory": "jsx",
"module": "es6",
"moduleResolution": "node",
"noImplicitAny": true,
"outDir": "./dist/",
"resolveJsonModule": true,
"target": "es6",
"lib": [
"DOM",
"ES2020"
]
}
}
.eslintrc.json
{
"env": {
"browser": true,
"es6": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"extends": [
"./.typescript.eslintrc.json"
]
}
.typescript.eslintrc.json
{
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"rules": {
"@typescript-eslint/no-unused-vars": "warn",
"no-unused-vars": "off"
}
}
]
}
The missing piece of the puzzle is the
parserOptions.project
.Actually,
parserOptions.jsxPragma
is also acceptable, but as the fragment name ("jsx") is already defined in the project, and the linter is able to get other useful information from the tsconfig file, it often makes more sense to setproject
if you can.The project points ESLint to the TypeScript configuration file which is critical for identifying the implicit call to
jsx()
.However, if linking your tsconfig to your eslint results in performance issues, then you can scale back and just use
jsxPragma
:To my knowledge, the typescript-parser options are only documented on the NPM module Readme. It's probably recorded elsewhere, but a quick search of the usual places™ didn't turn up any detailed docs.