diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/type_check_block.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/type_check_block.ts index cabb92f65ed..ef5697db619 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/type_check_block.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/type_check_block.ts @@ -1578,11 +1578,19 @@ class TcbUnclaimedOutputsOp extends TcbOp { // `$event` depending on the event name. For unknown event names, TypeScript resorts to the // base `Event` type. const handler = tcbCreateEventHandler(output, this.tcb, this.scope, EventParamType.Infer); - - if (elId === null) { - elId = this.scope.resolve(this.target); + let target: ts.Expression; + // Only check for `window` and `document` since in theory any target can be passed. + if (output.target === 'window' || output.target === 'document') { + target = ts.factory.createIdentifier(output.target); + } else if (elId === null) { + target = elId = this.scope.resolve(this.target); + } else { + target = elId; } - const propertyAccess = ts.factory.createPropertyAccessExpression(elId, 'addEventListener'); + const propertyAccess = ts.factory.createPropertyAccessExpression( + target, + 'addEventListener', + ); addParseSpanInfo(propertyAccess, output.keySpan); const call = ts.factory.createCallExpression( /* expression */ propertyAccess, diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/type_check_block_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/type_check_block_spec.ts index 28570116aa0..0f878354bea 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/type_check_block_spec.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/type_check_block_spec.ts @@ -357,6 +357,20 @@ describe('type check blocks', () => { ); }); + it('should generate code for event targeting `window`', () => { + const block = tcb(``); + expect(block).toContain( + 'window.addEventListener("scroll", ($event): any => { (this).handle(); });', + ); + }); + + it('should generate code for event targeting `document`', () => { + const block = tcb(``); + expect(block).toContain( + 'document.addEventListener("click", ($event): any => { (this).handle(); });', + ); + }); + it('should only generate directive declarations that have bindings or are referenced', () => { const TEMPLATE = `