I’m working on a Next.js project with TypeScript. It needs to interface with an external JavaScript library that isn’t TypeScript-enabled, which I’m loading by means of Next’s <Script>
component. It works fine in development, but when I try to build it, the build fails with the error Type error: Cannot find name 'x'.
, where x
is an object from the external library. I’ve tried declaring types for it but that’s a lot of very fiddly work for little gain, since it’s a well tested library. I’d like to just suppress the lint errors for the problem lines, but I can’t seem to get it working. Here’s what I’ve tried:
// eslint-disable-next-line
const y = new x.constructor();
or
const y = new x.constructor(); // eslint-disable-line
(I left this in while trying the rest of this list, since it didn’t work by itself.).eslintrc.json
with contents:
{
"extends": ["next/core-web-vitals", "next/typescript"],
"overrides": [
{
"files": ["**/*.ts", "**/*.tsx", "**/*.mts"],
"rules": {
"no-inline-config": "off"
}
}
]
}
next.config.js
with contents:
module.exports = {
eslint: {
"no-online-config": "off",
},
}
(This throws a warning, Unrecognized key(s) in object: 'noInlineConfig' at "eslint"
.)node_modules/next/bin/dist/bin/next
and remove the code .option("--no-inline-config", "Prevents comments from changing config or rules.")
.None of these made any difference, except for option 3, which threw a warning. For obvious reasons I don’t want to disable eslint completely, but I can’t see another option if I want this to build. What am I missing?
package.json
:
{
"name": "my-project",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@mui/icons-material": "^6.1.0",
"@mui/material": "^6.0.2",
"@mui/x-charts": "^7.17.0",
"@mui/x-date-pickers": "^7.16.0",
"dayjs": "^1.11.13",
"next": "^14.2.12",
"nuqs": "^1.20.0",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.8",
"typescript": "^5"
}
}
Type error: Cannot find name 'x'
That's not an ESLint report. That's a TypeScript report. Your whole investigation is going down the wrong path. 🙂
ESLint and TypeScript are both tools that give feedback on your code without running it (this is called "static analysis"). But they're two very tools:
eslint-plugin-next
Any report starting with "Type error:
" is a TypeScript type error. The way to suppress TypeScript type errors is with an inline // @ts-expect-error
(preferred) or // @ts-ignore
(less preferable). See https://www.totaltypescript.com/concepts/how-to-use-ts-expect-error for a good explanation.
Aside: instead of suppressing the TypeScript type error, it would be better to tell TypeScript about x
existing. That way it can give dev-time assistance for x
& let you know if you're using it wrong. https://www.typescriptlang.org/docs/handbook/declaration-files/by-example.html has docs. For example, to declare x
as a constant object with a .constructor
:
declare const x: {
constructor: typeof Object; // or typeof whatever class
}