From 1d2730790e00e2780e0771fe876194e2f859a933 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 8 Apr 2016 12:22:07 -0700 Subject: [PATCH] Report implicit any errors on destructuring parameter declarations Handles #6935 --- src/compiler/checker.ts | 10 ++- src/compiler/declarationEmitter.ts | 2 +- src/compiler/diagnosticMessages.json | 4 ++ ...structuringParameterDeclaration.errors.txt | 55 +++++++++++++++ ...citAnyDestructuringParameterDeclaration.js | 36 ++++++++++ ...tAnyDestructuringVarDeclaration.errors.txt | 69 +++++++++++++++++++ ...oImplicitAnyDestructuringVarDeclaration.js | 17 +++++ .../reference/wideningTuples5.errors.txt | 8 +-- ...citAnyDestructuringParameterDeclaration.ts | 11 +++ ...oImplicitAnyDestructuringVarDeclaration.ts | 10 +++ 10 files changed, 216 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/noImplicitAnyDestructuringParameterDeclaration.errors.txt create mode 100644 tests/baselines/reference/noImplicitAnyDestructuringParameterDeclaration.js create mode 100644 tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.errors.txt create mode 100644 tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.js create mode 100644 tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts create mode 100644 tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a357a2e0f71..95c07300773 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2836,11 +2836,16 @@ namespace ts { // pattern. Otherwise, it is the type any. function getTypeFromBindingElement(element: BindingElement, includePatternInType?: boolean): Type { if (element.initializer) { - return getWidenedType(checkExpressionCached(element.initializer)); + const type = checkExpressionCached(element.initializer); + reportErrorsFromWidening(element, type); + return getWidenedType(type); } if (isBindingPattern(element.name)) { return getTypeFromBindingPattern(element.name, includePatternInType); } + if (compilerOptions.noImplicitAny) { + reportImplicitAnyError(element, anyType); + } return anyType; } @@ -6799,6 +6804,9 @@ namespace ts { Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : Diagnostics.Parameter_0_implicitly_has_an_1_type; break; + case SyntaxKind.BindingElement: + diagnostic = Diagnostics.Binding_element_0_implicitly_has_an_1_type; + break; case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 423c1067e77..e0cf481a678 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -35,7 +35,7 @@ namespace ts { forEachExpectedEmitFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile); return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined); - function getDeclarationDiagnosticsFromFile({ declarationFilePath }, sources: SourceFile[], isBundledEmit: boolean) { + function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sources: SourceFile[], isBundledEmit: boolean) { emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sources, isBundledEmit); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6134f1e82b2..505442eb993 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2752,6 +2752,10 @@ "category": "Error", "code": 7030 }, + "Binding element '{0}' implicitly has an '{1}' type.": { + "category": "Error", + "code": 7031 + }, "You cannot rename this element.": { "category": "Error", "code": 8000 diff --git a/tests/baselines/reference/noImplicitAnyDestructuringParameterDeclaration.errors.txt b/tests/baselines/reference/noImplicitAnyDestructuringParameterDeclaration.errors.txt new file mode 100644 index 00000000000..a15f9c07cd3 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyDestructuringParameterDeclaration.errors.txt @@ -0,0 +1,55 @@ +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(1,14): error TS7031: Binding element 'a' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(1,19): error TS7031: Binding element 'b' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(1,23): error TS7006: Parameter 'c' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(1,26): error TS7006: Parameter 'd' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(3,14): error TS7031: Binding element 'a' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(3,31): error TS7031: Binding element 'b' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(3,42): error TS7006: Parameter 'c' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(3,57): error TS7006: Parameter 'd' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(7,20): error TS7008: Member 'b' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(7,30): error TS7008: Member 'b' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(9,14): error TS7031: Binding element 'a1' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(9,34): error TS7031: Binding element 'b1' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(9,54): error TS7006: Parameter 'c1' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts(9,70): error TS7006: Parameter 'd1' implicitly has an 'any' type. + + +==== tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts (14 errors) ==== + function f1([a], {b}, c, d) { // error + ~ +!!! error TS7031: Binding element 'a' implicitly has an 'any' type. + ~ +!!! error TS7031: Binding element 'b' implicitly has an 'any' type. + ~ +!!! error TS7006: Parameter 'c' implicitly has an 'any' type. + ~ +!!! error TS7006: Parameter 'd' implicitly has an 'any' type. + } + function f2([a = undefined], {b = null}, c = undefined, d = null) { // error + ~ +!!! error TS7031: Binding element 'a' implicitly has an 'any' type. + ~ +!!! error TS7031: Binding element 'b' implicitly has an 'any' type. + ~~~~~~~~~~~~~ +!!! error TS7006: Parameter 'c' implicitly has an 'any' type. + ~~~~~~~~ +!!! error TS7006: Parameter 'd' implicitly has an 'any' type. + } + function f3([a]: [any], {b}: { b: any }, c: any, d: any) { + } + function f4({b}: { b }, x: { b }) { // error in type instead + ~ +!!! error TS7008: Member 'b' implicitly has an 'any' type. + ~ +!!! error TS7008: Member 'b' implicitly has an 'any' type. + } + function f5([a1] = [undefined], {b1} = { b1: null }, c1 = undefined, d1 = null) { // error + ~~ +!!! error TS7031: Binding element 'a1' implicitly has an 'any' type. + ~~ +!!! error TS7031: Binding element 'b1' implicitly has an 'any' type. + ~~~~~~~~~~~~~~ +!!! error TS7006: Parameter 'c1' implicitly has an 'any' type. + ~~~~~~~~~ +!!! error TS7006: Parameter 'd1' implicitly has an 'any' type. + } \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitAnyDestructuringParameterDeclaration.js b/tests/baselines/reference/noImplicitAnyDestructuringParameterDeclaration.js new file mode 100644 index 00000000000..d587f8789a9 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyDestructuringParameterDeclaration.js @@ -0,0 +1,36 @@ +//// [noImplicitAnyDestructuringParameterDeclaration.ts] +function f1([a], {b}, c, d) { // error +} +function f2([a = undefined], {b = null}, c = undefined, d = null) { // error +} +function f3([a]: [any], {b}: { b: any }, c: any, d: any) { +} +function f4({b}: { b }, x: { b }) { // error in type instead +} +function f5([a1] = [undefined], {b1} = { b1: null }, c1 = undefined, d1 = null) { // error +} + +//// [noImplicitAnyDestructuringParameterDeclaration.js] +function f1(_a, _b, c, d) { + var a = _a[0]; + var b = _b.b; +} +function f2(_a, _b, c, d) { + var _c = _a[0], a = _c === void 0 ? undefined : _c; + var _d = _b.b, b = _d === void 0 ? null : _d; + if (c === void 0) { c = undefined; } + if (d === void 0) { d = null; } +} +function f3(_a, _b, c, d) { + var a = _a[0]; + var b = _b.b; +} +function f4(_a, x) { + var b = _a.b; +} +function f5(_a, _b, c1, d1) { + var a1 = (_a === void 0 ? [undefined] : _a)[0]; + var b1 = (_b === void 0 ? { b1: null } : _b).b1; + if (c1 === void 0) { c1 = undefined; } + if (d1 === void 0) { d1 = null; } +} diff --git a/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.errors.txt b/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.errors.txt new file mode 100644 index 00000000000..10d6b05c622 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.errors.txt @@ -0,0 +1,69 @@ +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,5): error TS1182: A destructuring declaration must have an initializer. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,6): error TS7031: Binding element 'a' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,10): error TS1182: A destructuring declaration must have an initializer. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,11): error TS7031: Binding element 'b' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,15): error TS7005: Variable 'c' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,18): error TS7005: Variable 'd' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,5): error TS1182: A destructuring declaration must have an initializer. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,6): error TS7031: Binding element 'a1' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,23): error TS1182: A destructuring declaration must have an initializer. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,24): error TS7031: Binding element 'b1' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,36): error TS7005: Variable 'c1' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,52): error TS7005: Variable 'd1' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(5,5): error TS1182: A destructuring declaration must have an initializer. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(5,18): error TS1182: A destructuring declaration must have an initializer. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(7,5): error TS1182: A destructuring declaration must have an initializer. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(7,13): error TS7008: Member 'b3' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(7,25): error TS7008: Member 'b3' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,6): error TS7031: Binding element 'a1' implicitly has an 'any' type. +tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,26): error TS7031: Binding element 'b1' implicitly has an 'any' type. + + +==== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts (19 errors) ==== + var [a], {b}, c, d; // error + ~~~ +!!! error TS1182: A destructuring declaration must have an initializer. + ~ +!!! error TS7031: Binding element 'a' implicitly has an 'any' type. + ~~~ +!!! error TS1182: A destructuring declaration must have an initializer. + ~ +!!! error TS7031: Binding element 'b' implicitly has an 'any' type. + ~ +!!! error TS7005: Variable 'c' implicitly has an 'any' type. + ~ +!!! error TS7005: Variable 'd' implicitly has an 'any' type. + + var [a1 = undefined], {b1 = null}, c1 = undefined, d1 = null; // error + ~~~~~~~~~~~~~~~~ +!!! error TS1182: A destructuring declaration must have an initializer. + ~~ +!!! error TS7031: Binding element 'a1' implicitly has an 'any' type. + ~~~~~~~~~~~ +!!! error TS1182: A destructuring declaration must have an initializer. + ~~ +!!! error TS7031: Binding element 'b1' implicitly has an 'any' type. + ~~ +!!! error TS7005: Variable 'c1' implicitly has an 'any' type. + ~~ +!!! error TS7005: Variable 'd1' implicitly has an 'any' type. + + var [a2]: [any], {b2}: { b2: any }, c2: any, d2: any; + ~~~~ +!!! error TS1182: A destructuring declaration must have an initializer. + ~~~~ +!!! error TS1182: A destructuring declaration must have an initializer. + + var {b3}: { b3 }, c3: { b3 }; // error in type instead + ~~~~ +!!! error TS1182: A destructuring declaration must have an initializer. + ~~ +!!! error TS7008: Member 'b3' implicitly has an 'any' type. + ~~ +!!! error TS7008: Member 'b3' implicitly has an 'any' type. + + var [a1] = [undefined], {b1} = { b1: null }, c1 = undefined, d1 = null; // error + ~~ +!!! error TS7031: Binding element 'a1' implicitly has an 'any' type. + ~~ +!!! error TS7031: Binding element 'b1' implicitly has an 'any' type. \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.js b/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.js new file mode 100644 index 00000000000..cbc15c01e9e --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.js @@ -0,0 +1,17 @@ +//// [noImplicitAnyDestructuringVarDeclaration.ts] +var [a], {b}, c, d; // error + +var [a1 = undefined], {b1 = null}, c1 = undefined, d1 = null; // error + +var [a2]: [any], {b2}: { b2: any }, c2: any, d2: any; + +var {b3}: { b3 }, c3: { b3 }; // error in type instead + +var [a1] = [undefined], {b1} = { b1: null }, c1 = undefined, d1 = null; // error + +//// [noImplicitAnyDestructuringVarDeclaration.js] +var a = (void 0)[0], b = (void 0).b, c, d; // error +var _a = (void 0)[0], a1 = _a === void 0 ? undefined : _a, _b = (void 0).b1, b1 = _b === void 0 ? null : _b, c1 = undefined, d1 = null; // error +var a2 = (void 0)[0], b2 = (void 0).b2, c2, d2; +var b3 = (void 0).b3, c3; // error in type instead +var a1 = [undefined][0], b1 = { b1: null }.b1, c1 = undefined, d1 = null; // error diff --git a/tests/baselines/reference/wideningTuples5.errors.txt b/tests/baselines/reference/wideningTuples5.errors.txt index bfd72079f55..cd6bf6161c9 100644 --- a/tests/baselines/reference/wideningTuples5.errors.txt +++ b/tests/baselines/reference/wideningTuples5.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/types/tuple/wideningTuples5.ts(1,6): error TS7005: Variable 'a' implicitly has an 'any' type. -tests/cases/conformance/types/tuple/wideningTuples5.ts(1,9): error TS7005: Variable 'b' implicitly has an 'any' type. +tests/cases/conformance/types/tuple/wideningTuples5.ts(1,6): error TS7031: Binding element 'a' implicitly has an 'any' type. +tests/cases/conformance/types/tuple/wideningTuples5.ts(1,9): error TS7031: Binding element 'b' implicitly has an 'any' type. ==== tests/cases/conformance/types/tuple/wideningTuples5.ts (2 errors) ==== var [a, b] = [undefined, null]; ~ -!!! error TS7005: Variable 'a' implicitly has an 'any' type. +!!! error TS7031: Binding element 'a' implicitly has an 'any' type. ~ -!!! error TS7005: Variable 'b' implicitly has an 'any' type. \ No newline at end of file +!!! error TS7031: Binding element 'b' implicitly has an 'any' type. \ No newline at end of file diff --git a/tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts b/tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts new file mode 100644 index 00000000000..9f4e579dcff --- /dev/null +++ b/tests/cases/compiler/noImplicitAnyDestructuringParameterDeclaration.ts @@ -0,0 +1,11 @@ +// @noimplicitany: true +function f1([a], {b}, c, d) { // error +} +function f2([a = undefined], {b = null}, c = undefined, d = null) { // error +} +function f3([a]: [any], {b}: { b: any }, c: any, d: any) { +} +function f4({b}: { b }, x: { b }) { // error in type instead +} +function f5([a1] = [undefined], {b1} = { b1: null }, c1 = undefined, d1 = null) { // error +} \ No newline at end of file diff --git a/tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts b/tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts new file mode 100644 index 00000000000..6988416d4de --- /dev/null +++ b/tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts @@ -0,0 +1,10 @@ +// @noimplicitany: true +var [a], {b}, c, d; // error + +var [a1 = undefined], {b1 = null}, c1 = undefined, d1 = null; // error + +var [a2]: [any], {b2}: { b2: any }, c2: any, d2: any; + +var {b3}: { b3 }, c3: { b3 }; // error in type instead + +var [a1] = [undefined], {b1} = { b1: null }, c1 = undefined, d1 = null; // error \ No newline at end of file