Skip to content

Angular produces incorrect transpiled code using typescript 5.0.4 but correct one using 4.9.x #25161

@tonivj5

Description

@tonivj5

Which @angular/* package(s) are the source of the bug?

compiler-cli, compiler, core

Is this a regression?

No

Description

Hi! I'm updating to Angular 16 and I've found a significally difference with the resulted compiled code between typescript 4.9.4 and 5.0.4

Here is an example of the problematic code:

export class IssueService {
  #throwIfUndefined = this.assertIfPropertyIsDefined();

  constructor(private readonly property) {}

  assertIfPropertyIsDefined() {
    if (!this.property) {
      throw new Error('the property should be defined');
    }
  }
}

Using Typescript 4.9.4 the service is transpiled to:

    __webpack_require__.r(__webpack_exports__);
        /* harmony export */
        __webpack_require__.d(__webpack_exports__, {
            /* harmony export */
            "IssueService": ()=>(/* binding */
            IssueService)/* harmony export */
        });
        /* harmony import */
        var _xxx_node_modules_babel_runtime_helpers_esm_classPrivateFieldInitSpec_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/classPrivateFieldInitSpec.js */
        4482);
        /* harmony import */
        var _xxx_node_modules_babel_runtime_helpers_esm_classPrivateFieldSet_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/classPrivateFieldSet.js */
        692);

        var _throwIfUndefined = /*#__PURE__*/
        new WeakMap();
        class IssueService {
            // Get attention to these lines
            constructor(property) {
                (0,
                _xxx_node_modules_babel_runtime_helpers_esm_classPrivateFieldInitSpec_js__WEBPACK_IMPORTED_MODULE_0__["default"])(this, _throwIfUndefined, {
                    writable: true,
                    value: void 0
                });
                this.property = property;
                (0,
                _xxx_node_modules_babel_runtime_helpers_esm_classPrivateFieldSet_js__WEBPACK_IMPORTED_MODULE_1__["default"])(this, _throwIfUndefined, this.assertIfPropertyIsDefined());
            }
            assertIfPropertyIsDefined() {
                if (!this.property) {
                    throw new Error('the property should be defined');
                }
            }
        }

But using Typescript 5.0.4 the service is transpiled to:

        __webpack_require__.r(__webpack_exports__);
        /* harmony export */
        __webpack_require__.d(__webpack_exports__, {
            /* harmony export */
            "IssueService": ()=>(/* binding */
            IssueService)/* harmony export */
        });
        /* harmony import */
        var xxx_node_modules_babel_runtime_helpers_esm_classPrivateFieldInitSpec_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/classPrivateFieldInitSpec.js */
        4482);

        var _throwIfUndefined = /*#__PURE__*/
        new WeakMap();
        class IssueService {
            constructor(property) {
                // The code is different and this code produces an exception where using 4.9.4 don't
                (0,
                _xxx_node_modules_babel_runtime_helpers_esm_classPrivateFieldInitSpec_js__WEBPACK_IMPORTED_MODULE_0__["default"])(this, _throwIfUndefined, {
                    writable: true,
                    value: this.assertIfPropertyIsDefined()
                });
                this.property = property;
            }
            assertIfPropertyIsDefined() {
                if (!this.property) {
                    throw new Error('the property should be defined');
                }
            }
        }

As you can see, the difference comes from the initialization of private fields. Well, I can't reproduce it on typescript side

Maybe it's a babel issue, but I don't know how to check it and I haven't found any issue about it...

I've prepared a minimal reproduction:

Please provide a link to a minimal reproduction of the bug

https://github.com/tonivj5/angular-ts-5-transpilation-issue

Please provide the exception or error you saw

Ucaught Error: the property should be defined
    at IssueService.assertIfPropertyIsDefined (issue.service.ts:8:13)
    at new IssueService (issue.service.ts:2:28)
    at 6747 (app.module.ts:13:17)
    at __webpack_require__ (bootstrap:19:1)
    at 4431 (issue.service.ts:10:3)
    at __webpack_require__ (bootstrap:19:1)
    at __webpack_exec__ (main.ts:7:36)
    at main.ts:7:36
    at __webpack_require__.O (chunk loaded:23:1)
    at main.ts:7:36
a

Please provide the environment you discovered this bug in (run ng version)

Node.js version v19.4.0 detected.
Odd numbered Node.js versions will not enter LTS status and should not be used for production. For more information, please see https://nodejs.org/en/about/releases/.

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 16.0.0
Node: 19.4.0 (Unsupported)
Package Manager: npm 9.2.0
OS: linux x64

Angular: 16.0.0
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1600.0
@angular-devkit/build-angular   16.0.0
@angular-devkit/core            16.0.0
@angular-devkit/schematics      16.0.0
@schematics/angular             16.0.0
rxjs                            7.8.1
typescript                      5.0.4
    
Warning: The current version of Node (19.4.0) is not supported by Angular.

Anything else?

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions