Target ES2022 + Module CommonJS silently produces code with TypeError in runtime
See original GitHub issueBug Report
This bug exists in my project, not only playground, but playground seem to also have bugs, because i can’t even seem to reliably reproduce it in the playground – sometimes it does not react on Target
change. But right now i have an opened playground tab with this bug.
I will duplicate the MRE code right here as a text. This is the source code
class Helper {
create(): boolean {
return true
}
}
export class Broken {
constructor(readonly facade: Helper) {
console.log(this.bug)
}
bug = this.facade.create()
}
new Broken(new Helper)
This is the compiled code with target: ES2022
and module: CommonJS
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Broken = void 0;
class Helper {
create() {
return true;
}
}
class Broken {
facade;
constructor(facade) {
this.facade = facade;
console.log(this.bug);
}
bug = this.facade.create();
}
exports.Broken = Broken;
new Broken(new Helper);
If run this JS – we will get TypeError
Cannot read properties of undefined (reading 'create')
⏯ Playground Link
Playground link with relevant code
I’m also sharing the playground link, but i assume it could produce the right code for you if you open it first time.
To reliable reproduce – change module
to Node16
and then to CommonJS
. You should see this result
![Screen Shot 2022-09-27 at 19 54 16](https://user-images.githubusercontent.com/9336742/192588709-e036c3cf-6cdc-4aa6-b070-85d267a4862a.png)
Issue Analytics
- State:
- Created a year ago
- Reactions:3
- Comments:9 (5 by maintainers)
Top Results From Across the Web
Add flag to not transpile dynamic `import()` when module is ...
Something like transpileDynamicImport which would be true by default and only take effect when "module": "CommonJS" . Motivating Example.
Read more >TSConfig Reference - Docs on every TSConfig option
The emitted JavaScript uses either CommonJS or ES2020 output depending on the file extension and the value of the type setting in the...
Read more >Unable to import ESM .ts module in node - Stack Overflow
In tsconfig.json (create one if not present) in compilerOptions add the following line: "module": "commonjs". Typescript info page here.
Read more >Modules • JavaScript for impatient programmers (ES2022 ...
18 gives an overview of these code formats. Note that for CommonJS modules and ECMAScript modules, two filename extensions are commonly used. Which...
Read more >Announcing TypeScript 4.7 RC - Microsoft Developer Blogs
In our beta release, we announced a stable target for our Node ESM ... This code works in CommonJS modules, but will fail...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
The code generation here is as-expected; the bug is the lack of error message to flag the use-before-init.
It looks like our expectation (prior to
useDefineForClassFields
), was that parameter property initializers are assigned before instance initializers, as evidenced by the emit whenuseDefineForClassFields
isfalse
:I would contend that the issue is our emit when
useDefineForClassFields
istrue
isn’t correctly moving the field initializers into the constructor. Really, the emit should be this: