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 a5971b595b..4864dfaec2 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 @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {AST, BindingPipe, BindingType, BoundTarget, DYNAMIC_TYPE, ImplicitReceiver, MethodCall, ParsedEventType, ParseSourceSpan, PropertyRead, PropertyWrite, SchemaMetadata, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstBoundText, TmplAstElement, TmplAstNode, TmplAstReference, TmplAstTemplate, TmplAstTextAttribute, TmplAstVariable} from '@angular/compiler'; +import {AST, BindingPipe, BindingType, BoundTarget, DYNAMIC_TYPE, ImplicitReceiver, MethodCall, ParsedEventType, ParseSourceSpan, PropertyRead, PropertyWrite, SchemaMetadata, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstBoundText, TmplAstElement, TmplAstIcu, TmplAstNode, TmplAstReference, TmplAstTemplate, TmplAstTextAttribute, TmplAstVariable} from '@angular/compiler'; import * as ts from 'typescript'; import {Reference} from '../../imports'; @@ -1333,6 +1333,8 @@ class Scope { this.checkAndAppendReferencesOfNode(node); } else if (node instanceof TmplAstBoundText) { this.opQueue.push(new TcbTextInterpolationOp(this.tcb, this, node)); + } else if (node instanceof TmplAstIcu) { + this.appendIcuExpressions(node); } } @@ -1459,6 +1461,17 @@ class Scope { this.appendDeepSchemaChecks(node.children); } } + + private appendIcuExpressions(node: TmplAstIcu): void { + for (const variable of Object.values(node.vars)) { + this.opQueue.push(new TcbTextInterpolationOp(this.tcb, this, variable)); + } + for (const placeholder of Object.values(node.placeholders)) { + if (placeholder instanceof TmplAstBoundText) { + this.opQueue.push(new TcbTextInterpolationOp(this.tcb, this, placeholder)); + } + } + } } interface TcbBoundInput { diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/diagnostics_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/diagnostics_spec.ts index 5838f2fc8e..0104b024a2 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/diagnostics_spec.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/diagnostics_spec.ts @@ -176,6 +176,21 @@ runInEachFileSystem(() => { ]); }); + it('checks expressions in ICUs', () => { + const messages = diagnose( + `{switch, plural, other { {{interpolation}} + {nestedSwitch, plural, other { {{nestedInterpolation}} }} + }}`, + `class TestComponent {}`); + + expect(messages.sort()).toEqual([ + `TestComponent.html(1, 13): Property 'switch' does not exist on type 'TestComponent'.`, + `TestComponent.html(1, 39): Property 'interpolation' does not exist on type 'TestComponent'.`, + `TestComponent.html(2, 14): Property 'nestedSwitch' does not exist on type 'TestComponent'.`, + `TestComponent.html(2, 46): Property 'nestedInterpolation' does not exist on type 'TestComponent'.`, + ]); + }); + it('produces diagnostics for pipes', () => { const messages = diagnose( `