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 0d417fae78..0410b72bc5 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
@@ -1622,7 +1622,7 @@ class TcbExpressionTranslator {
return null;
}
- const method = ts.createPropertyAccess(wrapForDiagnostics(receiver), ast.name);
+ const method = wrapForDiagnostics(receiver);
addParseSpanInfo(method, ast.nameSpan);
const args = ast.args.map(arg => this.translate(arg));
const node = ts.createCall(method, undefined, args);
diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/span_comments_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/span_comments_spec.ts
index caa312ce0a..6d8236e23e 100644
--- a/packages/compiler-cli/src/ngtsc/typecheck/test/span_comments_spec.ts
+++ b/packages/compiler-cli/src/ngtsc/typecheck/test/span_comments_spec.ts
@@ -71,7 +71,7 @@ describe('type check blocks diagnostics', () => {
const TEMPLATE = `{{ method(a, b) }}`;
expect(tcbWithSpans(TEMPLATE))
.toContain(
- '(_t2 /*27,39*/).method /*27,33*/(((ctx).a /*34,35*/) /*34,35*/, ((ctx).b /*37,38*/) /*37,38*/) /*27,39*/');
+ '(_t2 /*27,39*/) /*27,33*/(((ctx).a /*34,35*/) /*34,35*/, ((ctx).b /*37,38*/) /*37,38*/) /*27,39*/');
});
it('should annotate function calls', () => {
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 f81ac38469..82fc1d0583 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
@@ -106,7 +106,7 @@ describe('type check blocks', () => {
it('should handle method calls of template variables', () => {
const TEMPLATE = `{{a(1)}}`;
expect(tcb(TEMPLATE)).toContain('var _t2 = _t1.$implicit;');
- expect(tcb(TEMPLATE)).toContain('(_t2).a(1)');
+ expect(tcb(TEMPLATE)).toContain('(_t2)(1)');
});
it('should handle implicit vars when using microsyntax', () => {
@@ -114,6 +114,12 @@ describe('type check blocks', () => {
expect(tcb(TEMPLATE)).toContain('var _t2 = _t1.$implicit;');
});
+ it('should handle direct calls of an implicit template variable', () => {
+ const TEMPLATE = `
{{a(1)}}
`;
+ expect(tcb(TEMPLATE)).toContain('var _t2 = _t1.$implicit;');
+ expect(tcb(TEMPLATE)).toContain('(_t2)(1)');
+ });
+
describe('type constructors', () => {
it('should handle missing property bindings', () => {
const TEMPLATE = ``;
diff --git a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts
index 4e20f958ec..80d0f20199 100644
--- a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts
+++ b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts
@@ -1009,6 +1009,30 @@ export declare class AnimationEvent {
expect(diags.length).toBe(0);
});
+ it('should allow the implicit value of an NgFor to be invoked', () => {
+ env.tsconfig({fullTemplateTypeCheck: true, strictInputTypes: true});
+ env.write('test.ts', `
+ import {CommonModule} from '@angular/common';
+ import {Component, NgModule} from '@angular/core';
+
+ @Component({
+ selector: 'test',
+ template: '{{fn()}}
',
+ })
+ class TestCmp {
+ functions = [() => 1, () => 2];
+ }
+
+ @NgModule({
+ declarations: [TestCmp],
+ imports: [CommonModule],
+ })
+ class Module {}
+ `);
+
+ env.driveMain();
+ });
+
it('should infer the context of NgIf', () => {
env.tsconfig({strictTemplates: true});
env.write('test.ts', `