Node / Typescript / tslint errors on optional chaining operator (?.) in node_modules folder

224 Views Asked by At

I have a node script which runs fine on node version up to 17:

$ nvm use 17
Now using node v17.9.1 (npm v8.11.0)
$ cd src
$ npx tsc
$ npx node parser.js
$ cd ..

Beginning with node version 18 it errors because @npmcli is using an optional chaining operator:

$ nvm use 18
Now using node v18.16.0 (npm v9.5.1)
$ cd src
$ npx tsc
/Users/mles/.nvm/versions/node/v18.16.0/lib/node_modules/npm/node_modules/@npmcli/config/lib/index.js:485
        const raw = this.data.get(problem.where).raw?.[problem.from]
                                                     ^

SyntaxError: Unexpected token '.'

I get a similar error on node versions 19, 20, and 21. I'm guessing it has to do with my typescript or tslint setup, that does not like any optional chaining operator. I've tried ignoring any node_modules folder in my tslint.json file, but it does not solve the problem:

{
  "defaultSeverity": "error",
  "extends": [
    "tslint:recommended"
  ],
  "jsRules": {},
  "rules": {
    "no-console": false,
    "object-literal-sort-keys": [
      true,
      "match-declaration-order"
    ],
    "max-line-length": [
      true,
      200
    ],
    "typedef": [
      true,
      "member-variable-declaration",
      "variable-declaration"
    ]
  },
  "rulesDirectory": [],
  "compilerOptions": {
    "skipLibCheck": true
  },
  "linterOptions": {
    "exclude": [
        "node_modules"
    ]
  }
}

My tsconfig.json file:

{
  "compilerOptions": {
    "target": "ESNEXT",             
    "module": "commonjs",           
    "strict": true,                 
    "esModuleInterop": true,        
    "sourceMap": true
  }
}

Any hints how to allow the optional chaining operator in my setup?

4

There are 4 best solutions below

0
someRandomDev On BEST ANSWER

You can update your compilerOptions to include the specific rules for optional chaining. This will allow you to keep the strict mode on and keep validating the dependencies.

Your compilerOptions would look like this:

{
  "compilerOptions": {
    "target": "ESNEXT",             
    "module": "commonjs",           
    "strict": true,
    "esModuleInterop": true,        
    "sourceMap": true,
    "lib": ["ESNext", "DOM", "ES2020.OptionalChaining", "ES2020.NullishCoalescing"]
  }
}

(You might need to rebuild your TypeScript project (with npx tsc) afterwards for the change to be applied)

0
mapmath On

You can skip node_modules folder as below

{
  "compilerOptions": {
  "skipLibCheck": true
  },
}

OR

Command line tsc --skipLibCheck

OR

  "include": [
  "src/*"
  ],
  "exclude": [
  "node_modules",
  "./node_modules",
  "./node_modules/*",
  "./node_modules/@types/node/index.d.ts",
  ]
}
0
Chinz On

Seems like the problem might be in targeting esnext which prevents transpilation of some features. Try setting the target language to es2020 (or below).

0
Eliezer Berlin On

Optional Chaining Operators are an ES6 feature, though they seem to be first available in ES2020.

You should change your tsconfig.json file like so:

{
  "compilerOptions": {
    "target": "ES2020",             
    "module": "nodenext",           
    "strict": true,                 
    "esModuleInterop": true,        
    "sourceMap": true
  }
}

and if that doesn't work, setting both target and module to es2022 should fix it.