fix(ivy): handle empty bindings in template type checker (#31594)
When a template contains a binding without a value, the template parser creates an `EmptyExpr` node. This would previously be translated into an `undefined` value, which would cause a crash downstream as `undefined` is not included in the allowed type, so it was not handled properly. This commit prevents the crash by returning an actual expression for empty bindings. Fixes #30076 Fixes #30929 PR Close #31594
This commit is contained in:
parent
8e1a725462
commit
0db1b5d8f1
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {AST, ASTWithSource, AstVisitor, Binary, BindingPipe, Chain, Conditional, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, NonNullAssert, ParseSpan, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead} from '@angular/compiler';
|
||||
import {AST, ASTWithSource, AstVisitor, Binary, BindingPipe, Chain, Conditional, EmptyExpr, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, NonNullAssert, ParseSpan, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead} from '@angular/compiler';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {TypeCheckingConfig} from './api';
|
||||
|
@ -60,6 +60,11 @@ class AstTranslator implements AstVisitor {
|
|||
ast = ast.ast;
|
||||
}
|
||||
|
||||
// The `EmptyExpr` doesn't have a dedicated method on `AstVisitor`, so it's special cased here.
|
||||
if (ast instanceof EmptyExpr) {
|
||||
return UNDEFINED;
|
||||
}
|
||||
|
||||
// First attempt to let any custom resolution logic provide a translation for the given node.
|
||||
const resolved = this.maybeResolve(ast);
|
||||
if (resolved !== null) {
|
||||
|
|
|
@ -39,6 +39,16 @@ describe('type check blocks', () => {
|
|||
expect(tcb(TEMPLATE)).toContain('_t1.htmlFor = ("test");');
|
||||
});
|
||||
|
||||
it('should handle empty bindings', () => {
|
||||
const TEMPLATE = `<input [type]="">`;
|
||||
expect(tcb(TEMPLATE)).toContain('_t1.type = (undefined);');
|
||||
});
|
||||
|
||||
it('should handle bindings without value', () => {
|
||||
const TEMPLATE = `<input [type]>`;
|
||||
expect(tcb(TEMPLATE)).toContain('_t1.type = (undefined);');
|
||||
});
|
||||
|
||||
it('should handle implicit vars on ng-template', () => {
|
||||
const TEMPLATE = `<ng-template let-a></ng-template>`;
|
||||
expect(tcb(TEMPLATE)).toContain('var _t2 = _t1.$implicit;');
|
||||
|
|
Loading…
Reference in New Issue