fix(language-service): correctly type undefined

fixes #13412
closes #13414
This commit is contained in:
Chuck Jazdzewski 2016-12-12 18:11:56 -08:00 committed by Victor Berchet
parent 9ec0a4e105
commit 3a64ad895a
2 changed files with 19 additions and 4 deletions

View File

@ -209,22 +209,25 @@ class AstType implements ExpressionVisitor {
visitBinary(ast: Binary): Symbol {
// Treat undefined and null as other.
function normalize(kind: BuiltinType): BuiltinType {
function normalize(kind: BuiltinType, other: BuiltinType): BuiltinType {
switch (kind) {
case BuiltinType.Undefined:
case BuiltinType.Null:
return BuiltinType.Other;
return normalize(other, BuiltinType.Other);
}
return kind;
}
const leftType = this.getType(ast.left);
const rightType = this.getType(ast.right);
const leftKind = normalize(this.query.getTypeKind(leftType));
const rightKind = normalize(this.query.getTypeKind(rightType));
const leftRawKind = this.query.getTypeKind(leftType);
const rightRawKind = this.query.getTypeKind(rightType);
const leftKind = normalize(leftRawKind, rightRawKind);
const rightKind = normalize(rightRawKind, leftRawKind);
// The following swtich implements operator typing similar to the
// type production tables in the TypeScript specification.
// https://github.com/Microsoft/TypeScript/blob/v1.8.10/doc/spec.md#4.19
const operKind = leftKind << 8 | rightKind;
switch (ast.operation) {
case '*':
@ -411,6 +414,8 @@ class AstType implements ExpressionVisitor {
return this.query.getBuiltinType(BuiltinType.Boolean);
case null:
return this.query.getBuiltinType(BuiltinType.Null);
case undefined:
return this.query.getBuiltinType(BuiltinType.Undefined);
default:
switch (typeof ast.value) {
case 'string':

View File

@ -141,6 +141,16 @@ describe('diagnostics', () => {
});
});
// #13412
it('should not report an error for using undefined', () => {
const code =
` @Component({template: \`<div *ngIf="something === undefined"></div>\`}) export class MyComponent { something = 'foo'; }})`;
addCode(code, fileName => {
const diagnostics = ngService.getDiagnostics(fileName);
onlyModuleDiagnostics(diagnostics);
});
});
function addCode(code: string, cb: (fileName: string, content?: string) => void) {
const fileName = '/app/app.component.ts';
const originalContent = mockHost.getFileContent(fileName);