fix(compiler): don’t type check property access of literal maps (#19301)

This was the behavior in Ng4, so we put the stricter
check behind the `fullTemplateTypeCheck` flag.
PR Close #19301
This commit is contained in:
Tobias Bosch 2017-09-20 16:26:49 -07:00 committed by Igor Minar
parent 45747ed531
commit 04997c8418
2 changed files with 29 additions and 18 deletions

View File

@ -141,6 +141,12 @@ describe('ng type checker', () => {
'<div>{{"hello" | aPipe}}</div>', '<div>{{"hello" | aPipe}}</div>',
`Argument of type '"hello"' is not assignable to parameter of type 'number'.`, '0:5'); `Argument of type '"hello"' is not assignable to parameter of type 'number'.`, '0:5');
}); });
it('should report an index into a map expression', () => {
rejectOnlyWithFullTemplateTypeCheck(
'<div>{{ {a: 1}[name] }}</div>',
`Element implicitly has an 'any' type because type '{ a: number; }' has no index signature.`,
'0:5');
});
it('should report an invalid property on an exportAs directive', () => { it('should report an invalid property on an exportAs directive', () => {
rejectOnlyWithFullTemplateTypeCheck( rejectOnlyWithFullTemplateTypeCheck(
'<div aDir #aDir="aDir">{{aDir.fname}}</div>', '<div aDir #aDir="aDir">{{aDir.fname}}</div>',

View File

@ -251,26 +251,31 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
context: expression.context, context: expression.context,
value: convertPropertyBindingBuiltins( value: convertPropertyBindingBuiltins(
{ {
createLiteralArrayConverter: (argCount: number) => (args: o.Expression[]) => createLiteralArrayConverter: (argCount: number) => (args: o.Expression[]) => {
o.literalArr(args), const arr = o.literalArr(args);
createLiteralMapConverter: (keys: {key: string, quoted: boolean}[]) => // Note: The old view compiler used to use an `any` type
(values: o.Expression[]) => { // for arrays.
return this.options.fullTemplateTypeCheck ? arr : arr.cast(o.DYNAMIC_TYPE);
},
createLiteralMapConverter:
(keys: {key: string, quoted: boolean}[]) => (values: o.Expression[]) => {
const entries = keys.map((k, i) => ({ const entries = keys.map((k, i) => ({
key: k.key, key: k.key,
value: values[i], value: values[i],
quoted: k.quoted, quoted: k.quoted,
})); }));
return o.literalMap(entries); const map = o.literalMap(entries);
// Note: The old view compiler used to use an `any` type
// for maps.
return this.options.fullTemplateTypeCheck ? map : map.cast(o.DYNAMIC_TYPE);
}, },
createPipeConverter: (name: string, argCount: number) => (args: o.Expression[]) => { createPipeConverter: (name: string, argCount: number) => (args: o.Expression[]) => {
// Note: The old view compiler used to use an `any` type // Note: The old view compiler used to use an `any` type
// for pipe calls. // for pipes.
// We keep this behaivor behind a flag for now. const pipeExpr = this.options.fullTemplateTypeCheck ?
if (this.options.fullTemplateTypeCheck) { o.variable(this.pipeOutputVar(name)) :
return o.variable(this.pipeOutputVar(name)).callMethod('transform', args); o.variable(this.getOutputVar(o.BuiltinTypeName.Dynamic));
} else { return pipeExpr.callMethod('transform', args);
return o.variable(this.getOutputVar(o.BuiltinTypeName.Dynamic));
}
}, },
}, },
expression.value) expression.value)