Widen after sub-type-reduction took place

This commit is contained in:
Mohamed Hegazy 2017-02-09 14:55:07 -08:00
parent 914150f2f1
commit 24ddbe4b60
4 changed files with 44 additions and 4 deletions

View file

@ -3378,7 +3378,7 @@ namespace ts {
} }
// Return the inferred type for a variable, parameter, or property declaration // Return the inferred type for a variable, parameter, or property declaration
function getWidenedTypeForJSSpecialPropertyDeclaration(declaration: Declaration): Type { function getTypeForJSSpecialPropertyDeclaration(declaration: Declaration): Type {
const expression = declaration.kind === SyntaxKind.BinaryExpression ? <BinaryExpression>declaration : const expression = declaration.kind === SyntaxKind.BinaryExpression ? <BinaryExpression>declaration :
declaration.kind === SyntaxKind.PropertyAccessExpression ? <BinaryExpression>getAncestor(declaration, SyntaxKind.BinaryExpression) : declaration.kind === SyntaxKind.PropertyAccessExpression ? <BinaryExpression>getAncestor(declaration, SyntaxKind.BinaryExpression) :
undefined; undefined;
@ -3395,7 +3395,7 @@ namespace ts {
} }
} }
return getWidenedType(getWidenedLiteralType(checkExpressionCached(expression.right))); return getWidenedLiteralType(checkExpressionCached(expression.right));
} }
// Return the type implied by a binding pattern element. This is the type of the initializer of the element if // Return the type implied by a binding pattern element. This is the type of the initializer of the element if
@ -3552,7 +3552,7 @@ namespace ts {
// * className.prototype.method = expr // * className.prototype.method = expr
if (declaration.kind === SyntaxKind.BinaryExpression || if (declaration.kind === SyntaxKind.BinaryExpression ||
declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) { declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) {
type = getUnionType(map(symbol.declarations, getWidenedTypeForJSSpecialPropertyDeclaration), /*subtypeReduction*/ true); type = getWidenedType(getUnionType(map(symbol.declarations, getTypeForJSSpecialPropertyDeclaration), /*subtypeReduction*/ true));
} }
else { else {
type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true); type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);

View file

@ -0,0 +1,22 @@
tests/cases/compiler/bar.ts(2,1): error TS2322: Type '"string"' is not assignable to type 'number'.
==== tests/cases/compiler/foo.js (0 errors) ====
class C {
constructor() {
if (cond) {
this.p = null;
}
else {
this.p = 0;
}
}
}
==== tests/cases/compiler/bar.ts (1 errors) ====
(new C()).p = "string"; // Error
~~~~~~~~~~~
!!! error TS2322: Type '"string"' is not assignable to type 'number'.

View file

@ -21,7 +21,7 @@ C.prototype.m = function() {
this.nothing(); this.nothing();
>this.nothing() : any >this.nothing() : any
>this.nothing : any >this.nothing : any
>this : { m: any; } >this : { m: () => void; }
>nothing : any >nothing : any
} }
class X { class X {

View file

@ -0,0 +1,18 @@
// @allowJs: true
// @noEmit: true
// @filename: foo.js
class C {
constructor() {
if (cond) {
this.p = null;
}
else {
this.p = 0;
}
}
}
// @filename: bar.ts
(new C()).p = "string"; // Error