Do not report errors during contextual typecheck

Fixes #8229
This commit is contained in:
Sheetal Nandi
2016-04-21 13:25:43 -07:00
parent dfee3de3a6
commit 90d347e855
4 changed files with 230 additions and 76 deletions
+15 -13
View File
@@ -2873,7 +2873,7 @@ namespace ts {
// If the declaration specifies a binding pattern, use the type implied by the binding pattern
if (isBindingPattern(declaration.name)) {
return getTypeFromBindingPattern(<BindingPattern>declaration.name, /*includePatternInType*/ false);
return getTypeFromBindingPattern(<BindingPattern>declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
}
// No type specified and nothing can be inferred
@@ -2883,23 +2883,25 @@ namespace ts {
// Return the type implied by a binding pattern element. This is the type of the initializer of the element if
// one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
// pattern. Otherwise, it is the type any.
function getTypeFromBindingElement(element: BindingElement, includePatternInType?: boolean): Type {
function getTypeFromBindingElement(element: BindingElement, includePatternInType?: boolean, reportErrors?: boolean): Type {
if (element.initializer) {
const type = checkExpressionCached(element.initializer);
reportErrorsFromWidening(element, type);
if (reportErrors) {
reportErrorsFromWidening(element, type);
}
return getWidenedType(type);
}
if (isBindingPattern(element.name)) {
return getTypeFromBindingPattern(<BindingPattern>element.name, includePatternInType);
return getTypeFromBindingPattern(<BindingPattern>element.name, includePatternInType, reportErrors);
}
if (compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) {
if (reportErrors && compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) {
reportImplicitAnyError(element, anyType);
}
return anyType;
}
// Return the type implied by an object binding pattern
function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean): Type {
function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
const members: SymbolTable = {};
let hasComputedProperties = false;
forEach(pattern.elements, e => {
@@ -2913,7 +2915,7 @@ namespace ts {
const text = getTextOfPropertyName(name);
const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0);
const symbol = <TransientSymbol>createSymbol(flags, text);
symbol.type = getTypeFromBindingElement(e, includePatternInType);
symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
symbol.bindingElement = e;
members[symbol.name] = symbol;
});
@@ -2928,13 +2930,13 @@ namespace ts {
}
// Return the type implied by an array binding pattern
function getTypeFromArrayBindingPattern(pattern: BindingPattern, includePatternInType: boolean): Type {
function getTypeFromArrayBindingPattern(pattern: BindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
const elements = pattern.elements;
if (elements.length === 0 || elements[elements.length - 1].dotDotDotToken) {
return languageVersion >= ScriptTarget.ES6 ? createIterableType(anyType) : anyArrayType;
}
// If the pattern has at least one element, and no rest element, then it should imply a tuple type.
const elementTypes = map(elements, e => e.kind === SyntaxKind.OmittedExpression ? anyType : getTypeFromBindingElement(e, includePatternInType));
const elementTypes = map(elements, e => e.kind === SyntaxKind.OmittedExpression ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors));
if (includePatternInType) {
const result = createNewTupleType(elementTypes);
result.pattern = pattern;
@@ -2950,10 +2952,10 @@ namespace ts {
// used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring
// parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of
// the parameter.
function getTypeFromBindingPattern(pattern: BindingPattern, includePatternInType?: boolean): Type {
function getTypeFromBindingPattern(pattern: BindingPattern, includePatternInType?: boolean, reportErrors?: boolean): Type {
return pattern.kind === SyntaxKind.ObjectBindingPattern
? getTypeFromObjectBindingPattern(pattern, includePatternInType)
: getTypeFromArrayBindingPattern(pattern, includePatternInType);
? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors)
: getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors);
}
// Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type
@@ -8467,7 +8469,7 @@ namespace ts {
}
}
if (isBindingPattern(declaration.name)) {
return getTypeFromBindingPattern(<BindingPattern>declaration.name, /*includePatternInType*/ true);
return getTypeFromBindingPattern(<BindingPattern>declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false);
}
if (isBindingPattern(declaration.parent)) {
const parentDeclaration = declaration.parent.parent;
@@ -1,63 +0,0 @@
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(1,6): error TS7031: Binding element 'a' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(1,9): error TS7031: Binding element 'b' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(1,12): error TS7031: Binding element 'c' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(3,6): error TS7031: Binding element 'a2' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(3,22): error TS7031: Binding element 'b2' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(3,38): error TS7031: Binding element 'c2' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(5,6): error TS7031: Binding element 'a4' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(5,31): error TS7031: Binding element 'b4' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(7,6): error TS7031: Binding element 'x' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(7,9): error TS7031: Binding element 'y' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(7,12): error TS7031: Binding element 'z' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(9,6): error TS7031: Binding element 'x2' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(9,22): error TS7031: Binding element 'y2' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(9,38): error TS7031: Binding element 'z2' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(11,6): error TS7031: Binding element 'x4' implicitly has an 'any' type.
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts(11,37): error TS7031: Binding element 'y4' implicitly has an 'any' type.
==== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts (16 errors) ====
let [a, b, c] = [1, 2, 3]; // no error
~
!!! error TS7031: Binding element 'a' implicitly has an 'any' type.
~
!!! error TS7031: Binding element 'b' implicitly has an 'any' type.
~
!!! error TS7031: Binding element 'c' implicitly has an 'any' type.
let [a1 = 10, b1 = 10, c1 = 10] = [1, 2, 3]; // no error
let [a2 = undefined, b2 = undefined, c2 = undefined] = [1, 2, 3]; // no error
~~
!!! error TS7031: Binding element 'a2' implicitly has an 'any' type.
~~
!!! error TS7031: Binding element 'b2' implicitly has an 'any' type.
~~
!!! error TS7031: Binding element 'c2' implicitly has an 'any' type.
let [a3 = <any>undefined, b3 = <any>null, c3 = <any>undefined] = [1, 2, 3]; // no error
let [a4] = [<any>undefined], [b4] = [<any>null], c4 = <any>undefined, d4 = <any>null; // no error
~~
!!! error TS7031: Binding element 'a4' implicitly has an 'any' type.
~~
!!! error TS7031: Binding element 'b4' implicitly has an 'any' type.
let {x, y, z} = { x: 1, y: 2, z: 3 }; // no error
~
!!! error TS7031: Binding element 'x' implicitly has an 'any' type.
~
!!! error TS7031: Binding element 'y' implicitly has an 'any' type.
~
!!! error TS7031: Binding element 'z' implicitly has an 'any' type.
let {x1 = 10, y1 = 10, z1 = 10} = { x1: 1, y1: 2, z1: 3 }; // no error
let {x2 = undefined, y2 = undefined, z2 = undefined} = { x2: 1, y2: 2, z2: 3 }; // no error
~~
!!! error TS7031: Binding element 'x2' implicitly has an 'any' type.
~~
!!! error TS7031: Binding element 'y2' implicitly has an 'any' type.
~~
!!! error TS7031: Binding element 'z2' implicitly has an 'any' type.
let {x3 = <any>undefined, y3 = <any>null, z3 = <any>undefined} = { x3: 1, y3: 2, z3: 3 }; // no error
let {x4} = { x4: <any>undefined }, {y4} = { y4: <any>null }; // no error
~~
!!! error TS7031: Binding element 'x4' implicitly has an 'any' type.
~~
!!! error TS7031: Binding element 'y4' implicitly has an 'any' type.
@@ -0,0 +1,78 @@
=== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts ===
let [a, b, c] = [1, 2, 3]; // no error
>a : Symbol(a, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 0, 5))
>b : Symbol(b, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 0, 7))
>c : Symbol(c, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 0, 10))
let [a1 = 10, b1 = 10, c1 = 10] = [1, 2, 3]; // no error
>a1 : Symbol(a1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 1, 5))
>b1 : Symbol(b1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 1, 13))
>c1 : Symbol(c1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 1, 22))
let [a2 = undefined, b2 = undefined, c2 = undefined] = [1, 2, 3]; // no error
>a2 : Symbol(a2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 2, 5))
>undefined : Symbol(undefined)
>b2 : Symbol(b2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 2, 20))
>undefined : Symbol(undefined)
>c2 : Symbol(c2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 2, 36))
>undefined : Symbol(undefined)
let [a3 = <any>undefined, b3 = <any>null, c3 = <any>undefined] = [1, 2, 3]; // no error
>a3 : Symbol(a3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 3, 5))
>undefined : Symbol(undefined)
>b3 : Symbol(b3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 3, 25))
>c3 : Symbol(c3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 3, 41))
>undefined : Symbol(undefined)
let [a4] = [<any>undefined], [b4] = [<any>null], c4 = <any>undefined, d4 = <any>null; // no error
>a4 : Symbol(a4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 4, 5))
>undefined : Symbol(undefined)
>b4 : Symbol(b4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 4, 30))
>c4 : Symbol(c4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 4, 48))
>undefined : Symbol(undefined)
>d4 : Symbol(d4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 4, 69))
let {x, y, z} = { x: 1, y: 2, z: 3 }; // no error
>x : Symbol(x, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 5))
>y : Symbol(y, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 7))
>z : Symbol(z, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 10))
>x : Symbol(x, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 17))
>y : Symbol(y, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 23))
>z : Symbol(z, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 29))
let {x1 = 10, y1 = 10, z1 = 10} = { x1: 1, y1: 2, z1: 3 }; // no error
>x1 : Symbol(x1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 5))
>y1 : Symbol(y1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 13))
>z1 : Symbol(z1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 22))
>x1 : Symbol(x1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 35))
>y1 : Symbol(y1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 42))
>z1 : Symbol(z1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 49))
let {x2 = undefined, y2 = undefined, z2 = undefined} = { x2: 1, y2: 2, z2: 3 }; // no error
>x2 : Symbol(x2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 5))
>undefined : Symbol(undefined)
>y2 : Symbol(y2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 20))
>undefined : Symbol(undefined)
>z2 : Symbol(z2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 36))
>undefined : Symbol(undefined)
>x2 : Symbol(x2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 56))
>y2 : Symbol(y2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 63))
>z2 : Symbol(z2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 70))
let {x3 = <any>undefined, y3 = <any>null, z3 = <any>undefined} = { x3: 1, y3: 2, z3: 3 }; // no error
>x3 : Symbol(x3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 5))
>undefined : Symbol(undefined)
>y3 : Symbol(y3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 25))
>z3 : Symbol(z3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 41))
>undefined : Symbol(undefined)
>x3 : Symbol(x3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 66))
>y3 : Symbol(y3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 73))
>z3 : Symbol(z3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 80))
let {x4} = { x4: <any>undefined }, {y4} = { y4: <any>null }; // no error
>x4 : Symbol(x4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 10, 5))
>x4 : Symbol(x4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 10, 12))
>undefined : Symbol(undefined)
>y4 : Symbol(y4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 10, 36))
>y4 : Symbol(y4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 10, 43))
@@ -0,0 +1,137 @@
=== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts ===
let [a, b, c] = [1, 2, 3]; // no error
>a : number
>b : number
>c : number
>[1, 2, 3] : [number, number, number]
>1 : number
>2 : number
>3 : number
let [a1 = 10, b1 = 10, c1 = 10] = [1, 2, 3]; // no error
>a1 : number
>10 : number
>b1 : number
>10 : number
>c1 : number
>10 : number
>[1, 2, 3] : [number, number, number]
>1 : number
>2 : number
>3 : number
let [a2 = undefined, b2 = undefined, c2 = undefined] = [1, 2, 3]; // no error
>a2 : number
>undefined : undefined
>b2 : number
>undefined : undefined
>c2 : number
>undefined : undefined
>[1, 2, 3] : [number, number, number]
>1 : number
>2 : number
>3 : number
let [a3 = <any>undefined, b3 = <any>null, c3 = <any>undefined] = [1, 2, 3]; // no error
>a3 : number
><any>undefined : any
>undefined : undefined
>b3 : number
><any>null : any
>null : null
>c3 : number
><any>undefined : any
>undefined : undefined
>[1, 2, 3] : [number, number, number]
>1 : number
>2 : number
>3 : number
let [a4] = [<any>undefined], [b4] = [<any>null], c4 = <any>undefined, d4 = <any>null; // no error
>a4 : any
>[<any>undefined] : [any]
><any>undefined : any
>undefined : undefined
>b4 : any
>[<any>null] : [any]
><any>null : any
>null : null
>c4 : any
><any>undefined : any
>undefined : undefined
>d4 : any
><any>null : any
>null : null
let {x, y, z} = { x: 1, y: 2, z: 3 }; // no error
>x : number
>y : number
>z : number
>{ x: 1, y: 2, z: 3 } : { x: number; y: number; z: number; }
>x : number
>1 : number
>y : number
>2 : number
>z : number
>3 : number
let {x1 = 10, y1 = 10, z1 = 10} = { x1: 1, y1: 2, z1: 3 }; // no error
>x1 : number
>10 : number
>y1 : number
>10 : number
>z1 : number
>10 : number
>{ x1: 1, y1: 2, z1: 3 } : { x1?: number; y1?: number; z1?: number; }
>x1 : number
>1 : number
>y1 : number
>2 : number
>z1 : number
>3 : number
let {x2 = undefined, y2 = undefined, z2 = undefined} = { x2: 1, y2: 2, z2: 3 }; // no error
>x2 : number
>undefined : undefined
>y2 : number
>undefined : undefined
>z2 : number
>undefined : undefined
>{ x2: 1, y2: 2, z2: 3 } : { x2?: number; y2?: number; z2?: number; }
>x2 : number
>1 : number
>y2 : number
>2 : number
>z2 : number
>3 : number
let {x3 = <any>undefined, y3 = <any>null, z3 = <any>undefined} = { x3: 1, y3: 2, z3: 3 }; // no error
>x3 : number
><any>undefined : any
>undefined : undefined
>y3 : number
><any>null : any
>null : null
>z3 : number
><any>undefined : any
>undefined : undefined
>{ x3: 1, y3: 2, z3: 3 } : { x3?: number; y3?: number; z3?: number; }
>x3 : number
>1 : number
>y3 : number
>2 : number
>z3 : number
>3 : number
let {x4} = { x4: <any>undefined }, {y4} = { y4: <any>null }; // no error
>x4 : any
>{ x4: <any>undefined } : { x4: any; }
>x4 : any
><any>undefined : any
>undefined : undefined
>y4 : any
>{ y4: <any>null } : { y4: any; }
>y4 : any
><any>null : any
>null : null