mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(compiler-cli): set correct target when type checking events (#60561)
Currently the TCB generation code doesn't handle targeted events (e.g. `(document:click)`) which ends up binding to the current element and can have type inference implications. These changes take the event's `target` into account. PR Close #60561
This commit is contained in:
committed by
Alex Rickabaugh
parent
ec8c8f827e
commit
7e03af898e
@@ -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,
|
||||
|
||||
@@ -357,6 +357,20 @@ describe('type check blocks', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should generate code for event targeting `window`', () => {
|
||||
const block = tcb(`<button (window:scroll)="handle()"></button>`);
|
||||
expect(block).toContain(
|
||||
'window.addEventListener("scroll", ($event): any => { (this).handle(); });',
|
||||
);
|
||||
});
|
||||
|
||||
it('should generate code for event targeting `document`', () => {
|
||||
const block = tcb(`<button (document:click)="handle()"></button>`);
|
||||
expect(block).toContain(
|
||||
'document.addEventListener("click", ($event): any => { (this).handle(); });',
|
||||
);
|
||||
});
|
||||
|
||||
it('should only generate directive declarations that have bindings or are referenced', () => {
|
||||
const TEMPLATE = `
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user