Skip to content

Recent change in compiler-cli breaks jest-preset-angular  #48448

@jbjhjm

Description

@jbjhjm

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

compiler-cli

Is this a regression?

Yes

Description

I'm currently investigating an error that occurs in certain situations when running tests with jest-preset-angular and typescript 4.8. There are several issue reports over at jest-preset-angular, nrwl/nx and possibly others.

Error description

In short, this code will break jest / jest-preset-angular, throwing ReferenceError: anywhere_1 is not defined, when running typescript 4.8.

import {InterfaceFromInterfaceOnlyModule } from './anywhere' ;
class X {
	@MyDecorator() test():InterfaceFromInterfaceOnlyModule { ... }
}

A reproduction is available at https://github.com/jbjhjm/jest28-bug .

The error occurs when following circumstances are given:

  • use angular with typescript 4.8 (so ng 15) and jest with jest-preset-angular
  • Import nothing but an interface or type from a module
  • Use it on a method that is being decorated
  • Have emitDecoratorMetadata enabled

It seems like response type of a decorated method somehow "bleeds" into compiled javascript, where it causes an error because the type-only module does not exist anymore, ending up in a ReferenceError.

Origin of error

jest-preset-angular uses the downlevel_decorators_transform.ts from compiler-cli.
We managed to hunt the error down to a recent change in there.

#47167 modified that file in L565, replacing updateClassDeclaration by createClassDeclaration.

Here thymikee/jest-preset-angular#1199 (comment) , @n9niwas has shown a patch reverting that change to make it work as desired again, stating: "Idk for sure, but suspect that calling create* methods instead of update* makes TS program to forget information about whether a particular import is type-only or not."

@crisbeto , your insights might help here a lot.
I am not sure if downlevel_decorators_transform currently generates unexpected code, or if jest-preset-angular needs to update its own implementation to work correctly with the new code.
What's your estimation? Can you explain why createClassDeclaration is used now?


Related issues:

thymikee/jest-preset-angular#1199
thymikee/jest-preset-angular#1810
nrwl/nx#10660

Please provide a link to a minimal reproduction of the bug

https://github.com/jbjhjm/jest28-bug

Please provide the exception or error you saw

jest will throw `ReferenceError: xxx is not defined`

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

Angular CLI: 15.0.2
Node: 16.17.0
Package Manager: npm 8.15.0
OS: win32 x64

Angular: 15.0.2
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1500.2
@angular-devkit/build-angular   15.0.2
@angular-devkit/core            15.0.2
@angular-devkit/schematics      15.0.2
@schematics/angular             15.0.2
rxjs                            7.5.7
typescript                      4.8.4

Anything else?

No response

Metadata

Metadata

Assignees

Labels

P2The issue is important to a large percentage of users, with a workaroundarea: compilerIssues related to `ngc`, Angular's template compilerbugstate: has PR

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions