I have TypeScript 3.7 installed on a project, and I run tests with ava and ts-node. The issue I found is that compilation works as expected, but tests fail because ts-node doesn't recognize the syntax for nullish coalescence and optional chaining.
So if I have:
foobar?.foo?.bar ?? "default value"
I get errors all over the place. Isn't ts-node using the local typescript package to do compilation?
It does, but it is set to 3.6.4 still. Needs to be updated and then good to go I think?
TypeScript 3.7 is already supported, you would need to update your local installation.
@blakeembrey It's not supported though. As OP mentions, you'll see errors on optional chaining and nullish coalescing expressions when running ts-node, even though your local typescript version is set to 3.7.2.
One of the errors I'm getting:
Uncaught exception in src/tryCatch/tryCatch.test.ts
./node_modules/ts-node/src/index.ts:493
./src/tryCatch/tryCatch.ts:16
returnedValue = catchCallback?.(error);
^
SyntaxError: Unexpected token '.'
Module.m._compile (node_modules/ts-node/src/index.ts:493:23)
module.exports (node_modules/default-require-extensions/js.js:7:9)
require.extensions.<computed> (node_modules/ts-node/src/index.ts:496:12)
Tried a clean install with npm, still getting errors.
I noticed the fix is to change "target": "esnext" to "target": "es2018" in your tsconfig. No change required here.
By that error it is compiling correctly. The error is a node.js runtime error, not TypeScript compilation. As noted it鈥檚 failing because you鈥檙e compiling an output that node.js doesn鈥檛 understand yet.
Ohhhh yup. It seems to be a target issue. Thanks @keesvanlierop 馃槃
Is there any way to have nullish coalescing work on target esnext? The use case is that bigint's are only supported should esnext be targeted, rather than es2018.
@iwasaki-kenta my solution was to set target to es2018 and then:
"lib": [
"es2018",
"esnext.bigint"
]
So I have 2018 stuff, but I still support BigInt. It will only work expressed as BigInt("1") not like 1n 馃槥
OMG I had this same problem with a rollup / Vue / TypeScript combination.
"target": "es2018" solved it!
Also "target": "es2019" works for me but "target": "es2020" not yet.
For me "target": "es2019" and "target": "es2020" both works
I faced the same issue but the solution depends of the NodeJS version that runs the script.
With NodeJS 12, it worked with "target": "ES2018" and "target": "ES2019", but doesn't work with "target": "ES2020".
But I switched to NodeJS 14 and "target": "ES2020" worked fine.
So pay attention to the NodeJS version you are running your scripts
I can also confirm that setting my target to ES2020 didn't work, but ES2019 _did_ do the trick. I'm running Node v10.15.3.
this is going backwards it is werid.
Remember that TypeScript is compiling your code from .ts into .js, not ts-node. We simply use the compiler API, and the returned code is executed by node. What does your node version do when it executes the code being emitted from TypeScript? What kind of code is being emitted based on your compiler configuration?
If you set "target": "esnext", what code is TypeScript emitting? What does your node version do when it tries to execute this code?
Make sure you know the answers to these question. Otherwise, you're likely to confuse yourself and be unsure whether a problem is caused by your configuration or by ts-node. This will waste time and is probably not what you want.
nullish coalescing and optional chaining are supported in node >= v14.0.0
Just to make things a bit easier for new players, remember that "The target setting changes which JS features are downleveled", that is if the feature isn't natively supported by the NodeJS runtime version the TS compiler generates different code that will run on the node version. That's why es2020 works on node >= 14 but doesn't on node < 14
Also "target": "es2019" works for me but "target": "es2020" not yet.
I think @babel/preset-env was pretty wise to support targets: { node: 'current' }. Too bad that tsconfig.json doesn't!
Most helpful comment
I noticed the fix is to change
"target": "esnext"to"target": "es2018"in your tsconfig. No change required here.