From 2e5249835dc6c17106918e267213f8d8798532ee Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Jun 2019 16:54:42 -1000 Subject: [PATCH 1/9] Remove logic that pads array literals contextually typed by tuple types --- src/compiler/checker.ts | 50 ++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cf614ee201395..c62263957c73d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -722,6 +722,7 @@ namespace ts { NoIndexSignatures = 1 << 0, Writing = 1 << 1, CacheSymbol = 1 << 2, + NoTupleBoundsCheck = 1 << 3, } const enum CallbackCheck { @@ -5115,21 +5116,25 @@ namespace ts { } else if (isArrayLikeType(parentType)) { const indexType = getLiteralType(index); - const declaredType = getConstraintForLocation(getIndexedAccessType(parentType, indexType, declaration.name), declaration.name); + const accessFlags = hasDefaultValue(declaration) ? AccessFlags.NoTupleBoundsCheck : 0; + const declaredType = getConstraintForLocation(getIndexedAccessTypeOrUndefined(parentType, indexType, declaration.name, accessFlags) || errorType, declaration.name); type = getFlowTypeOfDestructuring(declaration, declaredType); } else { type = elementType; } } - // In strict null checking mode, if a default value of a non-undefined type is specified, remove - // undefined from the final type. - if (strictNullChecks && declaration.initializer && !(getFalsyFlags(checkDeclarationInitializer(declaration)) & TypeFlags.Undefined)) { - type = getTypeWithFacts(type, TypeFacts.NEUndefined); + if (!declaration.initializer) { + return type; } - return declaration.initializer && !getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration)) ? - getUnionType([type, checkDeclarationInitializer(declaration)], UnionReduction.Subtype) : - type; + if (getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration))) { + // In strict null checking mode, if a default value of a non-undefined type is specified, remove + // undefined from the final type. + return strictNullChecks && !(getFalsyFlags(checkDeclarationInitializer(declaration)) & TypeFlags.Undefined) ? + getTypeWithFacts(type, TypeFacts.NEUndefined) : + type; + } + return getUnionType([getTypeWithFacts(type, TypeFacts.NEUndefined), checkDeclarationInitializer(declaration)], UnionReduction.Subtype); } function getTypeForDeclarationFromJSDocComment(declaration: Node) { @@ -10131,7 +10136,7 @@ namespace ts { propType; } if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) { - if (accessNode && everyType(objectType, t => !(t).target.hasRestElement)) { + if (accessNode && everyType(objectType, t => !(t).target.hasRestElement) && !(accessFlags & AccessFlags.NoTupleBoundsCheck)) { const indexNode = getIndexNodeForAccessExpression(accessNode); if (isTupleType(objectType)) { error(indexNode, Diagnostics.Tuple_type_0_of_length_1_has_no_element_at_index_2, @@ -19196,26 +19201,7 @@ namespace ts { function getArrayLiteralTupleTypeIfApplicable(elementTypes: Type[], contextualType: Type | undefined, hasRestElement: boolean, elementCount = elementTypes.length, readonly = false) { // Infer a tuple type when the contextual type is or contains a tuple-like type if (readonly || (contextualType && forEachType(contextualType, isTupleLikeType))) { - const minLength = elementCount - (hasRestElement ? 1 : 0); - const pattern = contextualType && contextualType.pattern; - // If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting - // tuple type with the corresponding binding or assignment element types to make the lengths equal. - if (!hasRestElement && pattern && (pattern.kind === SyntaxKind.ArrayBindingPattern || pattern.kind === SyntaxKind.ArrayLiteralExpression)) { - const patternElements = (pattern).elements; - for (let i = elementCount; i < patternElements.length; i++) { - const e = patternElements[i]; - if (hasDefaultValue(e)) { - elementTypes.push((contextualType).typeArguments![i]); - } - else if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && (e).dotDotDotToken || e.kind === SyntaxKind.SpreadElement)) { - if (e.kind !== SyntaxKind.OmittedExpression) { - error(e, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value); - } - elementTypes.push(strictNullChecks ? implicitNeverType : undefinedWideningType); - } - } - } - return createTupleType(elementTypes, minLength, hasRestElement, readonly); + return createTupleType(elementTypes, elementCount - (hasRestElement ? 1 : 0), hasRestElement, readonly); } } @@ -23655,8 +23641,10 @@ namespace ts { if (isArrayLikeType(sourceType)) { // We create a synthetic expression so that getIndexedAccessType doesn't get confused // when the element is a SyntaxKind.ElementAccessExpression. - const elementType = getIndexedAccessType(sourceType, indexType, createSyntheticExpression(element, indexType)); - const type = getFlowTypeOfDestructuring(element, elementType); + const accessFlags = hasDefaultValue(element) ? AccessFlags.NoTupleBoundsCheck : 0; + const elementType = getIndexedAccessTypeOrUndefined(sourceType, indexType, createSyntheticExpression(element, indexType), accessFlags) || errorType; + const assignedType = hasDefaultValue(element) ? getTypeWithFacts(elementType, TypeFacts.NEUndefined) : elementType; + const type = getFlowTypeOfDestructuring(element, assignedType); return checkDestructuringAssignment(element, type, checkMode); } return checkDestructuringAssignment(element, elementType, checkMode); From fbb79400bb5cd6226fd019ddb9f400572f48b83f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Jun 2019 16:54:55 -1000 Subject: [PATCH 2/9] Accept new baselines --- ...nEmitDestructuringArrayPattern2.errors.txt | 12 +++++----- ...clarationEmitDestructuringArrayPattern2.js | 2 +- ...rationEmitDestructuringArrayPattern2.types | 8 +++---- .../declarationsAndAssignments.errors.txt | 24 +++++++++---------- .../declarationsAndAssignments.types | 18 +++++++------- ...BindingPatternAndAssignment1ES5.errors.txt | 12 +++++----- ...ArrayBindingPatternAndAssignment1ES5.types | 22 ++++++++--------- ...atternAndAssignment1ES5iterable.errors.txt | 12 +++++----- ...dingPatternAndAssignment1ES5iterable.types | 22 ++++++++--------- ...BindingPatternAndAssignment1ES6.errors.txt | 12 +++++----- ...ArrayBindingPatternAndAssignment1ES6.types | 22 ++++++++--------- ...rayBindingPatternAndAssignment2.errors.txt | 8 +++---- ...ingArrayBindingPatternAndAssignment2.types | 2 +- ...ingArrayBindingPatternAndAssignment3.types | 6 ++--- ...destructuringVariableDeclaration1ES5.types | 6 ++--- ...destructuringVariableDeclaration1ES6.types | 6 ++--- .../destructuringVariableDeclaration2.types | 2 +- .../reference/downlevelLetConst12.errors.txt | 8 +++---- .../reference/downlevelLetConst12.types | 8 +++---- ...plicitAnyDestructuringVarDeclaration.types | 2 +- .../reference/recursiveLetConst.types | 2 +- ...entArrayBindingPatternDefaultValues3.types | 18 +++++++------- 22 files changed, 117 insertions(+), 117 deletions(-) diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.errors.txt b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.errors.txt index 26998fd83ae83..e782352073ac0 100644 --- a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.errors.txt +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/declarationEmitDestructuringArrayPattern2.ts(4,6): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/compiler/declarationEmitDestructuringArrayPattern2.ts(4,11): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/compiler/declarationEmitDestructuringArrayPattern2.ts(4,16): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/compiler/declarationEmitDestructuringArrayPattern2.ts(4,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/compiler/declarationEmitDestructuringArrayPattern2.ts(4,11): error TS2493: Tuple type '[]' of length '0' has no element at index '1'. +tests/cases/compiler/declarationEmitDestructuringArrayPattern2.ts(4,16): error TS2493: Tuple type '[]' of length '0' has no element at index '2'. ==== tests/cases/compiler/declarationEmitDestructuringArrayPattern2.ts (3 errors) ==== @@ -9,11 +9,11 @@ tests/cases/compiler/declarationEmitDestructuringArrayPattern2.ts(4,16): error T var [x11 = 0, y11 = ""] = [1, "hello"]; var [a11, b11, c11] = []; ~~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ~~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '1'. ~~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '2'. var [a2, [b2, { x12, y12: c2 }]=["abc", { x12: 10, y12: false }]] = [1, ["hello", { x12: 5, y12: true }]]; diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.js b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.js index 818b3a6f7a97b..663b2d3567b2a 100644 --- a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.js +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.js @@ -22,7 +22,7 @@ var _m = [[x13, y13], { x: x13, y: y13 }], a3 = _m[0], b3 = _m[1]; //// [declarationEmitDestructuringArrayPattern2.d.ts] declare var x10: number, y10: string, z10: boolean; declare var x11: number, y11: string; -declare var a11: any, b11: any, c11: any; +declare var a11: undefined, b11: undefined, c11: undefined; declare var a2: number, b2: string, x12: number, c2: boolean; declare var x13: number, y13: string; declare var a3: (string | number)[], b3: { diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types index 37781e0a1aefb..b473e544ae161 100644 --- a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types @@ -20,10 +20,10 @@ var [x11 = 0, y11 = ""] = [1, "hello"]; >"hello" : "hello" var [a11, b11, c11] = []; ->a11 : any ->b11 : any ->c11 : any ->[] : [undefined?, undefined?, undefined?] +>a11 : undefined +>b11 : undefined +>c11 : undefined +>[] : [] var [a2, [b2, { x12, y12: c2 }]=["abc", { x12: 10, y12: false }]] = [1, ["hello", { x12: 5, y12: true }]]; >a2 : number diff --git a/tests/baselines/reference/declarationsAndAssignments.errors.txt b/tests/baselines/reference/declarationsAndAssignments.errors.txt index b13aacbfbc3fe..d6f0ab3873a65 100644 --- a/tests/baselines/reference/declarationsAndAssignments.errors.txt +++ b/tests/baselines/reference/declarationsAndAssignments.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(5,16): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(5,16): error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(22,17): error TS2353: Object literal may only specify known properties, and 'x' does not exist in type '{}'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(22,23): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{}'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(23,25): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: any; }'. @@ -6,11 +6,11 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(24,19): tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(28,28): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: any; }'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(29,22): error TS2353: Object literal may only specify known properties, and 'x' does not exist in type '{ y: any; }'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(58,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'y' must be of type 'string | number', but here has type 'string'. -tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(62,10): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(62,13): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(62,16): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(63,13): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(63,16): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(62,10): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(62,13): error TS2493: Tuple type '[]' of length '0' has no element at index '1'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(62,16): error TS2493: Tuple type '[]' of length '0' has no element at index '2'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(63,13): error TS2493: Tuple type '[number]' of length '1' has no element at index '1'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(63,16): error TS2493: Tuple type '[number]' of length '1' has no element at index '2'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(67,9): error TS2461: Type '{}' is not an array type. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(68,9): error TS2461: Type '{ 0: number; 1: number; }' is not an array type. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,11): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. @@ -29,7 +29,7 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9): var [x, y] = [1, "hello"]; var [x, y, z] = [1, "hello"]; ~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. var [,, x] = [0, 1, 2]; var x: number; var y: string; @@ -103,16 +103,16 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9): function f8() { var [a, b, c] = []; // Error, [] is an empty tuple ~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '1'. ~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '2'. var [d, e, f] = [1]; // Error, [1] is a tuple ~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[number]' of length '1' has no element at index '1'. ~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[number]' of length '1' has no element at index '2'. } function f9() { diff --git a/tests/baselines/reference/declarationsAndAssignments.types b/tests/baselines/reference/declarationsAndAssignments.types index 89ddd0eb5e5fc..ed157a7e69ce5 100644 --- a/tests/baselines/reference/declarationsAndAssignments.types +++ b/tests/baselines/reference/declarationsAndAssignments.types @@ -23,8 +23,8 @@ function f0() { var [x, y, z] = [1, "hello"]; >x : number >y : string ->z : any ->[1, "hello"] : [number, string, undefined?] +>z : undefined +>[1, "hello"] : [number, string] >1 : 1 >"hello" : "hello" @@ -255,16 +255,16 @@ function f8() { >f8 : () => void var [a, b, c] = []; // Error, [] is an empty tuple ->a : any ->b : any ->c : any ->[] : [undefined?, undefined?, undefined?] +>a : undefined +>b : undefined +>c : undefined +>[] : [] var [d, e, f] = [1]; // Error, [1] is a tuple >d : number ->e : any ->f : any ->[1] : [number, undefined?, undefined?] +>e : undefined +>f : undefined +>[1] : [number] >1 : 1 } diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.errors.txt index 1f1bc85757b07..17a9dc13f9a1e 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5.ts(43,6): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5.ts(44,8): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5.ts(44,18): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5.ts(43,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5.ts(44,8): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5.ts(44,18): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ==== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5.ts (3 errors) ==== @@ -48,12 +48,12 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss var [c0, c1] = [...temp]; var [c2] = []; ~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] ~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. var [[c5], c6]: [[string|number], boolean] = [[1], true]; var [, c7] = [1, 2, 3]; var [,,, c8] = [1, 2, 3, 4]; diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types index 03990bc084651..d9e9cb494d2ab 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types @@ -92,19 +92,19 @@ var [c0, c1] = [...temp]; >temp : number[] var [c2] = []; ->c2 : any ->[] : [undefined?] +>c2 : undefined +>[] : [] var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] ->c3 : any ->c4 : any ->[[[]], [[[[]]]]] : [[[undefined?]], [[[[undefined?]]]]] ->[[]] : [[undefined?]] ->[] : [undefined?] ->[[[[]]]] : [[[[undefined?]]]] ->[[[]]] : [[[undefined?]]] ->[[]] : [[undefined?]] ->[] : [undefined?] +>c3 : undefined +>c4 : undefined +>[[[]], [[[[]]]]] : [[[]], [[[[]]]]] +>[[]] : [[]] +>[] : [] +>[[[[]]]] : [[[[]]]] +>[[[]]] : [[[]]] +>[[]] : [[]] +>[] : [] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.errors.txt index 6a2647013fb0b..21e239114cb6a 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(43,6): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(44,8): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(44,18): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(43,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(44,8): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(44,18): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ==== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES5iterable.ts (3 errors) ==== @@ -48,12 +48,12 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss var [c0, c1] = [...temp]; var [c2] = []; ~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] ~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. var [[c5], c6]: [[string|number], boolean] = [[1], true]; var [, c7] = [1, 2, 3]; var [,,, c8] = [1, 2, 3, 4]; diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types index cb2e801823270..6d232030fae60 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types @@ -92,19 +92,19 @@ var [c0, c1] = [...temp]; >temp : number[] var [c2] = []; ->c2 : any ->[] : [undefined?] +>c2 : undefined +>[] : [] var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] ->c3 : any ->c4 : any ->[[[]], [[[[]]]]] : [[[undefined?]], [[[[undefined?]]]]] ->[[]] : [[undefined?]] ->[] : [undefined?] ->[[[[]]]] : [[[[undefined?]]]] ->[[[]]] : [[[undefined?]]] ->[[]] : [[undefined?]] ->[] : [undefined?] +>c3 : undefined +>c4 : undefined +>[[[]], [[[[]]]]] : [[[]], [[[[]]]]] +>[[]] : [[]] +>[] : [] +>[[[[]]]] : [[[[]]]] +>[[[]]] : [[[]]] +>[[]] : [[]] +>[] : [] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.errors.txt index 4dc6085e66274..3dc897456aa0c 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES6.ts(43,6): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES6.ts(44,8): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES6.ts(44,18): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES6.ts(43,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES6.ts(44,8): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES6.ts(44,18): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ==== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment1ES6.ts (3 errors) ==== @@ -48,12 +48,12 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss var [c0, c1] = [...temp]; var [c2] = []; ~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] ~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. var [[c5], c6]: [[string|number], boolean] = [[1], true]; var [, c7] = [1, 2, 3]; var [,,, c8] = [1, 2, 3, 4]; diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types index 9a00291f79c64..feb0116ea0461 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types @@ -92,19 +92,19 @@ var [c0, c1] = [...temp]; >temp : number[] var [c2] = []; ->c2 : any ->[] : [undefined?] +>c2 : undefined +>[] : [] var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] ->c3 : any ->c4 : any ->[[[]], [[[[]]]]] : [[[undefined?]], [[[[undefined?]]]]] ->[[]] : [[undefined?]] ->[] : [undefined?] ->[[[[]]]] : [[[[undefined?]]]] ->[[[]]] : [[[undefined?]]] ->[[]] : [[undefined?]] ->[] : [undefined?] +>c3 : undefined +>c4 : undefined +>[[[]], [[[[]]]]] : [[[]], [[[[]]]]] +>[[]] : [[]] +>[] : [] +>[[[[]]]] : [[[[]]]] +>[[[]]] : [[[]]] +>[[]] : [[]] +>[] : [] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt index 6d16229f33336..dd01ac9651928 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2461: Type 'undefined' is not an array type. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2461: Type 'undefined' is not an array type. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2493: Tuple type '[]' of length '0' has no element at index '1'. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(4,5): error TS2461: Type 'undefined' is not an array type. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(9,51): error TS2322: Type 'number' is not assignable to type 'boolean'. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(22,5): error TS2739: Type 'number[]' is missing the following properties from type '[number, number]': 0, 1 @@ -16,11 +16,11 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss ~~~~ !!! error TS2461: Type 'undefined' is not an array type. ~~~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ~~~~~~ !!! error TS2461: Type 'undefined' is not an array type. ~~~~~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '1'. var [[a2], [[a3]]] = undefined // Error ~~~~~~~~~~~~~~ !!! error TS2461: Type 'undefined' is not an array type. diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types index 77681f8d8c840..86723735bb544 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types @@ -4,7 +4,7 @@ var [[a0], [[a1]]] = [] // Error >a0 : any >a1 : any ->[] : [undefined?, undefined?] +>[] : [] var [[a2], [[a3]]] = undefined // Error >a2 : any diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.types index 0fb81ba6aa308..5a0e03dda6e56 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.types @@ -3,7 +3,7 @@ const [a, b = a] = [1]; // ok >a : any >b : any >a : any ->[1] : [number, any?] +>[1] : [number] >1 : 1 const [c, d = c, e = e] = [1]; // error for e = e @@ -12,7 +12,7 @@ const [c, d = c, e = e] = [1]; // error for e = e >c : any >e : any >e : any ->[1] : [number, any?, any?] +>[1] : [number] >1 : 1 const [f, g = f, h = i, i = f] = [1]; // error for h = i @@ -23,7 +23,7 @@ const [f, g = f, h = i, i = f] = [1]; // error for h = i >i : any >i : any >f : any ->[1] : [number, any?, any?, any?] +>[1] : [number] >1 : 1 (function ([a, b = a]) { // ok diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5.types b/tests/baselines/reference/destructuringVariableDeclaration1ES5.types index fc153be7c601a..0e1a89eff93a3 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5.types @@ -151,9 +151,9 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; >f4 : number >f5 : number > : undefined ->{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, undefined?]; } ->f : [number, number, { f3: number; f5: number; }, undefined?] ->[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, undefined?] +>{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }]; } +>f : [number, number, { f3: number; f5: number; }] +>[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }] >1 : 1 >2 : 2 >{ f3: 4, f5: 0 } : { f3: number; f5: number; } diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES6.types b/tests/baselines/reference/destructuringVariableDeclaration1ES6.types index bf00e1955ca0d..d47ec0e0d7428 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES6.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES6.types @@ -151,9 +151,9 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; >f4 : number >f5 : number > : undefined ->{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, undefined?]; } ->f : [number, number, { f3: number; f5: number; }, undefined?] ->[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, undefined?] +>{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }]; } +>f : [number, number, { f3: number; f5: number; }] +>[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }] >1 : 1 >2 : 2 >{ f3: 4, f5: 0 } : { f3: number; f5: number; } diff --git a/tests/baselines/reference/destructuringVariableDeclaration2.types b/tests/baselines/reference/destructuringVariableDeclaration2.types index ddb560f4e24c0..3b4fe8af85f2d 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration2.types +++ b/tests/baselines/reference/destructuringVariableDeclaration2.types @@ -60,7 +60,7 @@ var [c1, c2, { c3: c4, c5 }, , ...c6] = [1, 2, { c3: 4, c5: 0 }]; // Error >c5 : number > : undefined >c6 : [] ->[1, 2, { c3: 4, c5: 0 }] : [number, number, { c3: number; c5: number; }, undefined?] +>[1, 2, { c3: 4, c5: 0 }] : [number, number, { c3: number; c5: number; }] >1 : 1 >2 : 2 >{ c3: 4, c5: 0 } : { c3: number; c5: number; } diff --git a/tests/baselines/reference/downlevelLetConst12.errors.txt b/tests/baselines/reference/downlevelLetConst12.errors.txt index 7d5c682820795..8c4bcb9d4f737 100644 --- a/tests/baselines/reference/downlevelLetConst12.errors.txt +++ b/tests/baselines/reference/downlevelLetConst12.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/downlevelLetConst12.ts(6,6): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/compiler/downlevelLetConst12.ts(9,8): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/compiler/downlevelLetConst12.ts(6,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/compiler/downlevelLetConst12.ts(9,8): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. ==== tests/cases/compiler/downlevelLetConst12.ts (2 errors) ==== @@ -10,10 +10,10 @@ tests/cases/compiler/downlevelLetConst12.ts(9,8): error TS2525: Initializer prov let [baz] = []; ~~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. let {a: baz2} = { a: 1 }; const [baz3] = [] ~~~~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. const {a: baz4} = { a: 1 }; \ No newline at end of file diff --git a/tests/baselines/reference/downlevelLetConst12.types b/tests/baselines/reference/downlevelLetConst12.types index 25316e67eb468..3f64d06788c5e 100644 --- a/tests/baselines/reference/downlevelLetConst12.types +++ b/tests/baselines/reference/downlevelLetConst12.types @@ -11,8 +11,8 @@ const bar = 1; >1 : 1 let [baz] = []; ->baz : any ->[] : [undefined?] +>baz : undefined +>[] : [] let {a: baz2} = { a: 1 }; >a : any @@ -22,8 +22,8 @@ let {a: baz2} = { a: 1 }; >1 : 1 const [baz3] = [] ->baz3 : any ->[] : [undefined?] +>baz3 : undefined +>[] : [] const {a: baz4} = { a: 1 }; >a : any diff --git a/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.types b/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.types index 823af52080699..8a60da05e6dc4 100644 --- a/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.types +++ b/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.types @@ -44,5 +44,5 @@ var [a4] = [undefined], {b4} = { b4: null }, c4 = undefined, d4 = null; // error var [a5 = undefined] = []; // error >a5 : any >undefined : undefined ->[] : [undefined?] +>[] : [] diff --git a/tests/baselines/reference/recursiveLetConst.types b/tests/baselines/reference/recursiveLetConst.types index 90b0d7baab1f7..7525d6242b61b 100644 --- a/tests/baselines/reference/recursiveLetConst.types +++ b/tests/baselines/reference/recursiveLetConst.types @@ -49,7 +49,7 @@ for (let [v] of v) { } let [x2 = x2] = [] >x2 : any >x2 : any ->[] : [any?] +>[] : [] let z0 = () => z0; >z0 : () => any diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues3.types b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues3.types index fb9e4aca6b5c9..2f9d1dac6e3b0 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues3.types +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues3.types @@ -234,11 +234,11 @@ let multiRobotAInfo: (string | string[])[]; [nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] = multiRobotB; >[nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] = multiRobotB : [string, string[]] ->[nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] : [string, [string?, string?]] +>[nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] : [string, []] >nameMB = "helloNoName" : "helloNoName" >nameMB : string >"helloNoName" : "helloNoName" ->[primarySkillB = "noSkill", secondarySkillB = "noSkill"] = [] : [string?, string?] +>[primarySkillB = "noSkill", secondarySkillB = "noSkill"] = [] : [] >[primarySkillB = "noSkill", secondarySkillB = "noSkill"] : [string, string] >primarySkillB = "noSkill" : "noSkill" >primarySkillB : string @@ -246,16 +246,16 @@ let multiRobotAInfo: (string | string[])[]; >secondarySkillB = "noSkill" : "noSkill" >secondarySkillB : string >"noSkill" : "noSkill" ->[] : [string?, string?] +>[] : [] >multiRobotB : [string, string[]] [nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] = getMultiRobotB(); >[nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] = getMultiRobotB() : [string, string[]] ->[nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] : [string, [string?, string?]] +>[nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] : [string, []] >nameMB = "helloNoName" : "helloNoName" >nameMB : string >"helloNoName" : "helloNoName" ->[primarySkillB = "noSkill", secondarySkillB = "noSkill"] = [] : [string?, string?] +>[primarySkillB = "noSkill", secondarySkillB = "noSkill"] = [] : [] >[primarySkillB = "noSkill", secondarySkillB = "noSkill"] : [string, string] >primarySkillB = "noSkill" : "noSkill" >primarySkillB : string @@ -263,17 +263,17 @@ let multiRobotAInfo: (string | string[])[]; >secondarySkillB = "noSkill" : "noSkill" >secondarySkillB : string >"noSkill" : "noSkill" ->[] : [string?, string?] +>[] : [] >getMultiRobotB() : [string, string[]] >getMultiRobotB : () => [string, string[]] [nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] = >[nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] = ["trimmer", ["trimming", "edging"]] : [string, [string, string]] ->[nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] : [string, [string?, string?]] +>[nameMB = "helloNoName", [primarySkillB = "noSkill", secondarySkillB = "noSkill"] = []] : [string, []] >nameMB = "helloNoName" : "helloNoName" >nameMB : string >"helloNoName" : "helloNoName" ->[primarySkillB = "noSkill", secondarySkillB = "noSkill"] = [] : [string?, string?] +>[primarySkillB = "noSkill", secondarySkillB = "noSkill"] = [] : [] >[primarySkillB = "noSkill", secondarySkillB = "noSkill"] : [string, string] >primarySkillB = "noSkill" : "noSkill" >primarySkillB : string @@ -281,7 +281,7 @@ let multiRobotAInfo: (string | string[])[]; >secondarySkillB = "noSkill" : "noSkill" >secondarySkillB : string >"noSkill" : "noSkill" ->[] : [string?, string?] +>[] : [] ["trimmer", ["trimming", "edging"]]; >["trimmer", ["trimming", "edging"]] : [string, [string, string]] From b7b7a6626c4ffe6d3d7450025da88548c419ac08 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Jun 2019 17:09:22 -1000 Subject: [PATCH 3/9] Add regression tests --- tests/cases/compiler/destructuringTuple.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/cases/compiler/destructuringTuple.ts b/tests/cases/compiler/destructuringTuple.ts index c6a8431da0b3a..1b92b239875f6 100644 --- a/tests/cases/compiler/destructuringTuple.ts +++ b/tests/cases/compiler/destructuringTuple.ts @@ -7,3 +7,9 @@ const [a, b, c, ...rest] = tuple; declare var receiver: typeof tuple; [...receiver] = tuple; + +// Repros from #32140 + +const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); + +const [oops2] = [1, 2, 3].reduce((acc: number[], e) => acc.concat(e), []); From 4c99084b383b0664fdc46c7307148ab1b12bae0a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Jun 2019 17:10:09 -1000 Subject: [PATCH 4/9] Accept new baselines --- .../reference/destructuringTuple.errors.txt | 23 +++++++++++ .../baselines/reference/destructuringTuple.js | 9 +++++ .../reference/destructuringTuple.symbols | 24 +++++++++++ .../reference/destructuringTuple.types | 40 +++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 tests/baselines/reference/destructuringTuple.errors.txt diff --git a/tests/baselines/reference/destructuringTuple.errors.txt b/tests/baselines/reference/destructuringTuple.errors.txt new file mode 100644 index 0000000000000..cd366409dc807 --- /dev/null +++ b/tests/baselines/reference/destructuringTuple.errors.txt @@ -0,0 +1,23 @@ +tests/cases/compiler/destructuringTuple.ts(11,8): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/compiler/destructuringTuple.ts(11,60): error TS2345: Argument of type 'number' is not assignable to parameter of type 'ConcatArray'. + + +==== tests/cases/compiler/destructuringTuple.ts (2 errors) ==== + declare var tuple: [boolean, number, ...string[]]; + + const [a, b, c, ...rest] = tuple; + + declare var receiver: typeof tuple; + + [...receiver] = tuple; + + // Repros from #32140 + + const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); + ~~~~~ +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'ConcatArray'. + + const [oops2] = [1, 2, 3].reduce((acc: number[], e) => acc.concat(e), []); + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringTuple.js b/tests/baselines/reference/destructuringTuple.js index a8a0bc6f5e3d1..8d580dfba518e 100644 --- a/tests/baselines/reference/destructuringTuple.js +++ b/tests/baselines/reference/destructuringTuple.js @@ -6,9 +6,18 @@ const [a, b, c, ...rest] = tuple; declare var receiver: typeof tuple; [...receiver] = tuple; + +// Repros from #32140 + +const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); + +const [oops2] = [1, 2, 3].reduce((acc: number[], e) => acc.concat(e), []); //// [destructuringTuple.js] "use strict"; var a = tuple[0], b = tuple[1], c = tuple[2], rest = tuple.slice(3); receiver = tuple.slice(0); +// Repros from #32140 +var oops1 = [1, 2, 3].reduce(function (accu, el) { return accu.concat(el); }, [])[0]; +var oops2 = [1, 2, 3].reduce(function (acc, e) { return acc.concat(e); }, [])[0]; diff --git a/tests/baselines/reference/destructuringTuple.symbols b/tests/baselines/reference/destructuringTuple.symbols index 73480505c3b14..82e006ca8c194 100644 --- a/tests/baselines/reference/destructuringTuple.symbols +++ b/tests/baselines/reference/destructuringTuple.symbols @@ -17,3 +17,27 @@ declare var receiver: typeof tuple; >receiver : Symbol(receiver, Decl(destructuringTuple.ts, 4, 11)) >tuple : Symbol(tuple, Decl(destructuringTuple.ts, 0, 11)) +// Repros from #32140 + +const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); +>oops1 : Symbol(oops1, Decl(destructuringTuple.ts, 10, 7)) +>[1, 2, 3].reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>accu : Symbol(accu, Decl(destructuringTuple.ts, 10, 34)) +>el : Symbol(el, Decl(destructuringTuple.ts, 10, 39)) +>accu.concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>accu : Symbol(accu, Decl(destructuringTuple.ts, 10, 34)) +>concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>el : Symbol(el, Decl(destructuringTuple.ts, 10, 39)) + +const [oops2] = [1, 2, 3].reduce((acc: number[], e) => acc.concat(e), []); +>oops2 : Symbol(oops2, Decl(destructuringTuple.ts, 12, 7)) +>[1, 2, 3].reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>acc : Symbol(acc, Decl(destructuringTuple.ts, 12, 34)) +>e : Symbol(e, Decl(destructuringTuple.ts, 12, 48)) +>acc.concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>acc : Symbol(acc, Decl(destructuringTuple.ts, 12, 34)) +>concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>e : Symbol(e, Decl(destructuringTuple.ts, 12, 48)) + diff --git a/tests/baselines/reference/destructuringTuple.types b/tests/baselines/reference/destructuringTuple.types index fe3bf84746fc2..466e4495a1646 100644 --- a/tests/baselines/reference/destructuringTuple.types +++ b/tests/baselines/reference/destructuringTuple.types @@ -20,3 +20,43 @@ declare var receiver: typeof tuple; >receiver : [boolean, number, ...string[]] >tuple : [boolean, number, ...string[]] +// Repros from #32140 + +const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); +>oops1 : undefined +>[1, 2, 3].reduce((accu, el) => accu.concat(el), []) : [] +>[1, 2, 3].reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>[1, 2, 3] : number[] +>1 : 1 +>2 : 2 +>3 : 3 +>reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>(accu, el) => accu.concat(el) : (accu: [], el: number) => any +>accu : [] +>el : number +>accu.concat(el) : any +>accu.concat : { (...items: ConcatArray[]): never[]; (...items: ConcatArray[]): never[]; } +>accu : [] +>concat : { (...items: ConcatArray[]): never[]; (...items: ConcatArray[]): never[]; } +>el : number +>[] : [] + +const [oops2] = [1, 2, 3].reduce((acc: number[], e) => acc.concat(e), []); +>oops2 : number +>[1, 2, 3].reduce((acc: number[], e) => acc.concat(e), []) : number[] +>[1, 2, 3].reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>[1, 2, 3] : number[] +>1 : 1 +>2 : 2 +>3 : 3 +>reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>(acc: number[], e) => acc.concat(e) : (acc: number[], e: number) => number[] +>acc : number[] +>e : number +>acc.concat(e) : number[] +>acc.concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } +>acc : number[] +>concat : { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } +>e : number +>[] : never[] + From eb1b2251b8d8ed28f81dd8c1f18347b28ed00ac0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 30 Jun 2019 08:02:18 -1000 Subject: [PATCH 5/9] Pad tuple type initializers of parameter array binding elements --- src/compiler/checker.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c62263957c73d..533231a575be5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24233,10 +24233,13 @@ namespace ts { function checkDeclarationInitializer(declaration: HasExpressionInitializer) { const initializer = getEffectiveInitializer(declaration)!; const type = getTypeOfExpression(initializer, /*cache*/ true); + const padded = isParameter(declaration) && declaration.name.kind === SyntaxKind.ArrayBindingPattern && + isTupleType(type) && !type.target.hasRestElement && getTypeReferenceArity(type) < declaration.name.elements.length ? + padTupleType(type, declaration.name) : type; const widened = getCombinedNodeFlags(declaration) & NodeFlags.Const || isDeclarationReadonly(declaration) || isTypeAssertion(initializer) || - isLiteralOfContextualType(type, getContextualType(initializer)) ? type : getWidenedLiteralType(type); + isLiteralOfContextualType(padded, getContextualType(initializer)) ? padded : getWidenedLiteralType(padded); if (isInJSFile(declaration)) { if (widened.flags & TypeFlags.Nullable) { reportImplicitAny(declaration, anyType); @@ -24250,6 +24253,22 @@ namespace ts { return widened; } + function padTupleType(type: TupleTypeReference, pattern: ArrayBindingPattern) { + const patternElements = pattern.elements; + const arity = getTypeReferenceArity(type); + const elementTypes = arity ? type.typeArguments!.slice() : []; + for (let i = arity; i < patternElements.length; i++) { + const e = patternElements[i]; + if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && (e).dotDotDotToken)) { + elementTypes.push(!isOmittedExpression(e) && hasDefaultValue(e) ? getTypeFromBindingElement(e, /*includePatternInType*/ false, /*reportErrors*/ false) : anyType); + if (!isOmittedExpression(e) && !hasDefaultValue(e)) { + reportImplicitAny(e, anyType); + } + } + } + return createTupleType(elementTypes, type.target.minLength, /*hasRestElement*/ false, type.target.readonly); + } + function isLiteralOfContextualType(candidateType: Type, contextualType: Type | undefined): boolean { if (contextualType) { if (contextualType.flags & TypeFlags.UnionOrIntersection) { From 32f1b4e56c820f2647817b8dbd42bc182521925d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 30 Jun 2019 08:02:53 -1000 Subject: [PATCH 6/9] Accept new baselines --- ...estructuringVariableDeclaration1ES5iterable.types | 6 +++--- .../destructuringWithLiteralInitializers.types | 4 ++-- .../reference/downlevelLetConst16.errors.txt | 8 ++++---- tests/baselines/reference/downlevelLetConst16.types | 12 ++++++------ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types b/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types index 9c943356d80b5..1476797e74a92 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types @@ -151,9 +151,9 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; >f4 : number >f5 : number > : undefined ->{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, undefined?]; } ->f : [number, number, { f3: number; f5: number; }, undefined?] ->[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, undefined?] +>{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }]; } +>f : [number, number, { f3: number; f5: number; }] +>[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }] >1 : 1 >2 : 2 >{ f3: 4, f5: 0 } : { f3: number; f5: number; } diff --git a/tests/baselines/reference/destructuringWithLiteralInitializers.types b/tests/baselines/reference/destructuringWithLiteralInitializers.types index f19c1cf2b7ead..9a64518a8cba0 100644 --- a/tests/baselines/reference/destructuringWithLiteralInitializers.types +++ b/tests/baselines/reference/destructuringWithLiteralInitializers.types @@ -274,7 +274,7 @@ function g4([x, y = 0] = [0]) { } >x : number >y : number >0 : 0 ->[0] : [number, number?] +>[0] : [number] >0 : 0 g4(); @@ -295,7 +295,7 @@ function g5([x = 0, y = 0] = []) { } >0 : 0 >y : number >0 : 0 ->[] : [number?, number?] +>[] : [] g5(); >g5() : void diff --git a/tests/baselines/reference/downlevelLetConst16.errors.txt b/tests/baselines/reference/downlevelLetConst16.errors.txt index 955c79378fe30..664fadccac9dc 100644 --- a/tests/baselines/reference/downlevelLetConst16.errors.txt +++ b/tests/baselines/reference/downlevelLetConst16.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/downlevelLetConst16.ts(151,15): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. -tests/cases/compiler/downlevelLetConst16.ts(164,17): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/compiler/downlevelLetConst16.ts(151,15): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +tests/cases/compiler/downlevelLetConst16.ts(164,17): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. tests/cases/compiler/downlevelLetConst16.ts(195,14): error TS2461: Type 'undefined' is not an array type. tests/cases/compiler/downlevelLetConst16.ts(202,15): error TS2339: Property 'a' does not exist on type 'undefined'. tests/cases/compiler/downlevelLetConst16.ts(216,16): error TS2461: Type 'undefined' is not an array type. @@ -159,7 +159,7 @@ tests/cases/compiler/downlevelLetConst16.ts(223,17): error TS2339: Property 'a' } for (let [y] = []; ;) { ~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. use(y); } for (let {a: z} = {a: 1}; ;) { @@ -174,7 +174,7 @@ tests/cases/compiler/downlevelLetConst16.ts(223,17): error TS2339: Property 'a' } for (const [y] = []; ;) { ~ -!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +!!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. use(y); } for (const {a: z} = { a: 1 }; ;) { diff --git a/tests/baselines/reference/downlevelLetConst16.types b/tests/baselines/reference/downlevelLetConst16.types index 450773fd9bb31..ac9dc31eb042a 100644 --- a/tests/baselines/reference/downlevelLetConst16.types +++ b/tests/baselines/reference/downlevelLetConst16.types @@ -515,13 +515,13 @@ function foo3() { >x : any } for (let [y] = []; ;) { ->y : any ->[] : [undefined?] +>y : undefined +>[] : [] use(y); >use(y) : any >use : (a: any) => any ->y : any +>y : undefined } for (let {a: z} = {a: 1}; ;) { >a : any @@ -554,13 +554,13 @@ function foo4() { >x : 1 } for (const [y] = []; ;) { ->y : any ->[] : [undefined?] +>y : undefined +>[] : [] use(y); >use(y) : any >use : (a: any) => any ->y : any +>y : undefined } for (const {a: z} = { a: 1 }; ;) { >a : any From 5ad3d1bf084b356b20b7a94c5f81a1695e021840 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 30 Jun 2019 08:18:01 -1000 Subject: [PATCH 7/9] Add more tests --- .../destructuringWithLiteralInitializers2.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts diff --git a/tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts b/tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts new file mode 100644 index 0000000000000..7654a9ac3367f --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts @@ -0,0 +1,29 @@ +// @strict: true + +function f00([x, y]) {} +function f01([x, y] = []) {} +function f02([x, y] = [1]) {} +function f03([x, y] = [1, 'foo']) {} + +function f10([x = 0, y]) {} +function f11([x = 0, y] = []) {} +function f12([x = 0, y] = [1]) {} +function f13([x = 0, y] = [1, 'foo']) {} + +function f20([x = 0, y = 'bar']) {} +function f21([x = 0, y = 'bar'] = []) {} +function f22([x = 0, y = 'bar'] = [1]) {} +function f23([x = 0, y = 'bar'] = [1, 'foo']) {} + +declare const nx: number | undefined; +declare const sx: string | undefined; + +function f30([x = 0, y = 'bar']) {} +function f31([x = 0, y = 'bar'] = []) {} +function f32([x = 0, y = 'bar'] = [nx]) {} +function f33([x = 0, y = 'bar'] = [nx, sx]) {} + +function f40([x = 0, y = 'bar']) {} +function f41([x = 0, y = 'bar'] = []) {} +function f42([x = 0, y = 'bar'] = [sx]) {} +function f43([x = 0, y = 'bar'] = [sx, nx]) {} From cc7a24c27f1428a7c476a704f778a6579a287633 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 30 Jun 2019 08:18:08 -1000 Subject: [PATCH 8/9] Accept new baselines --- ...cturingWithLiteralInitializers2.errors.txt | 55 ++++++ .../destructuringWithLiteralInitializers2.js | 92 ++++++++++ ...tructuringWithLiteralInitializers2.symbols | 113 ++++++++++++ ...estructuringWithLiteralInitializers2.types | 165 ++++++++++++++++++ 4 files changed, 425 insertions(+) create mode 100644 tests/baselines/reference/destructuringWithLiteralInitializers2.errors.txt create mode 100644 tests/baselines/reference/destructuringWithLiteralInitializers2.js create mode 100644 tests/baselines/reference/destructuringWithLiteralInitializers2.symbols create mode 100644 tests/baselines/reference/destructuringWithLiteralInitializers2.types diff --git a/tests/baselines/reference/destructuringWithLiteralInitializers2.errors.txt b/tests/baselines/reference/destructuringWithLiteralInitializers2.errors.txt new file mode 100644 index 0000000000000..983f853f9a44f --- /dev/null +++ b/tests/baselines/reference/destructuringWithLiteralInitializers2.errors.txt @@ -0,0 +1,55 @@ +tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts(1,15): error TS7031: Binding element 'x' implicitly has an 'any' type. +tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts(1,18): error TS7031: Binding element 'y' implicitly has an 'any' type. +tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts(2,15): error TS7031: Binding element 'x' implicitly has an 'any' type. +tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts(2,18): error TS7031: Binding element 'y' implicitly has an 'any' type. +tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts(3,18): error TS7031: Binding element 'y' implicitly has an 'any' type. +tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts(6,22): error TS7031: Binding element 'y' implicitly has an 'any' type. +tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts(7,22): error TS7031: Binding element 'y' implicitly has an 'any' type. +tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts(8,22): error TS7031: Binding element 'y' implicitly has an 'any' type. + + +==== tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts (8 errors) ==== + function f00([x, y]) {} + ~ +!!! error TS7031: Binding element 'x' implicitly has an 'any' type. + ~ +!!! error TS7031: Binding element 'y' implicitly has an 'any' type. + function f01([x, y] = []) {} + ~ +!!! error TS7031: Binding element 'x' implicitly has an 'any' type. + ~ +!!! error TS7031: Binding element 'y' implicitly has an 'any' type. + function f02([x, y] = [1]) {} + ~ +!!! error TS7031: Binding element 'y' implicitly has an 'any' type. + function f03([x, y] = [1, 'foo']) {} + + function f10([x = 0, y]) {} + ~ +!!! error TS7031: Binding element 'y' implicitly has an 'any' type. + function f11([x = 0, y] = []) {} + ~ +!!! error TS7031: Binding element 'y' implicitly has an 'any' type. + function f12([x = 0, y] = [1]) {} + ~ +!!! error TS7031: Binding element 'y' implicitly has an 'any' type. + function f13([x = 0, y] = [1, 'foo']) {} + + function f20([x = 0, y = 'bar']) {} + function f21([x = 0, y = 'bar'] = []) {} + function f22([x = 0, y = 'bar'] = [1]) {} + function f23([x = 0, y = 'bar'] = [1, 'foo']) {} + + declare const nx: number | undefined; + declare const sx: string | undefined; + + function f30([x = 0, y = 'bar']) {} + function f31([x = 0, y = 'bar'] = []) {} + function f32([x = 0, y = 'bar'] = [nx]) {} + function f33([x = 0, y = 'bar'] = [nx, sx]) {} + + function f40([x = 0, y = 'bar']) {} + function f41([x = 0, y = 'bar'] = []) {} + function f42([x = 0, y = 'bar'] = [sx]) {} + function f43([x = 0, y = 'bar'] = [sx, nx]) {} + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringWithLiteralInitializers2.js b/tests/baselines/reference/destructuringWithLiteralInitializers2.js new file mode 100644 index 0000000000000..1f3ee956144c6 --- /dev/null +++ b/tests/baselines/reference/destructuringWithLiteralInitializers2.js @@ -0,0 +1,92 @@ +//// [destructuringWithLiteralInitializers2.ts] +function f00([x, y]) {} +function f01([x, y] = []) {} +function f02([x, y] = [1]) {} +function f03([x, y] = [1, 'foo']) {} + +function f10([x = 0, y]) {} +function f11([x = 0, y] = []) {} +function f12([x = 0, y] = [1]) {} +function f13([x = 0, y] = [1, 'foo']) {} + +function f20([x = 0, y = 'bar']) {} +function f21([x = 0, y = 'bar'] = []) {} +function f22([x = 0, y = 'bar'] = [1]) {} +function f23([x = 0, y = 'bar'] = [1, 'foo']) {} + +declare const nx: number | undefined; +declare const sx: string | undefined; + +function f30([x = 0, y = 'bar']) {} +function f31([x = 0, y = 'bar'] = []) {} +function f32([x = 0, y = 'bar'] = [nx]) {} +function f33([x = 0, y = 'bar'] = [nx, sx]) {} + +function f40([x = 0, y = 'bar']) {} +function f41([x = 0, y = 'bar'] = []) {} +function f42([x = 0, y = 'bar'] = [sx]) {} +function f43([x = 0, y = 'bar'] = [sx, nx]) {} + + +//// [destructuringWithLiteralInitializers2.js] +"use strict"; +function f00(_a) { + var x = _a[0], y = _a[1]; +} +function f01(_a) { + var _b = _a === void 0 ? [] : _a, x = _b[0], y = _b[1]; +} +function f02(_a) { + var _b = _a === void 0 ? [1] : _a, x = _b[0], y = _b[1]; +} +function f03(_a) { + var _b = _a === void 0 ? [1, 'foo'] : _a, x = _b[0], y = _b[1]; +} +function f10(_a) { + var _b = _a[0], x = _b === void 0 ? 0 : _b, y = _a[1]; +} +function f11(_a) { + var _b = _a === void 0 ? [] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, y = _b[1]; +} +function f12(_a) { + var _b = _a === void 0 ? [1] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, y = _b[1]; +} +function f13(_a) { + var _b = _a === void 0 ? [1, 'foo'] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, y = _b[1]; +} +function f20(_a) { + var _b = _a[0], x = _b === void 0 ? 0 : _b, _c = _a[1], y = _c === void 0 ? 'bar' : _c; +} +function f21(_a) { + var _b = _a === void 0 ? [] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, _d = _b[1], y = _d === void 0 ? 'bar' : _d; +} +function f22(_a) { + var _b = _a === void 0 ? [1] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, _d = _b[1], y = _d === void 0 ? 'bar' : _d; +} +function f23(_a) { + var _b = _a === void 0 ? [1, 'foo'] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, _d = _b[1], y = _d === void 0 ? 'bar' : _d; +} +function f30(_a) { + var _b = _a[0], x = _b === void 0 ? 0 : _b, _c = _a[1], y = _c === void 0 ? 'bar' : _c; +} +function f31(_a) { + var _b = _a === void 0 ? [] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, _d = _b[1], y = _d === void 0 ? 'bar' : _d; +} +function f32(_a) { + var _b = _a === void 0 ? [nx] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, _d = _b[1], y = _d === void 0 ? 'bar' : _d; +} +function f33(_a) { + var _b = _a === void 0 ? [nx, sx] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, _d = _b[1], y = _d === void 0 ? 'bar' : _d; +} +function f40(_a) { + var _b = _a[0], x = _b === void 0 ? 0 : _b, _c = _a[1], y = _c === void 0 ? 'bar' : _c; +} +function f41(_a) { + var _b = _a === void 0 ? [] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, _d = _b[1], y = _d === void 0 ? 'bar' : _d; +} +function f42(_a) { + var _b = _a === void 0 ? [sx] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, _d = _b[1], y = _d === void 0 ? 'bar' : _d; +} +function f43(_a) { + var _b = _a === void 0 ? [sx, nx] : _a, _c = _b[0], x = _c === void 0 ? 0 : _c, _d = _b[1], y = _d === void 0 ? 'bar' : _d; +} diff --git a/tests/baselines/reference/destructuringWithLiteralInitializers2.symbols b/tests/baselines/reference/destructuringWithLiteralInitializers2.symbols new file mode 100644 index 0000000000000..44224ac22a491 --- /dev/null +++ b/tests/baselines/reference/destructuringWithLiteralInitializers2.symbols @@ -0,0 +1,113 @@ +=== tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts === +function f00([x, y]) {} +>f00 : Symbol(f00, Decl(destructuringWithLiteralInitializers2.ts, 0, 0)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 0, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 0, 16)) + +function f01([x, y] = []) {} +>f01 : Symbol(f01, Decl(destructuringWithLiteralInitializers2.ts, 0, 23)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 1, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 1, 16)) + +function f02([x, y] = [1]) {} +>f02 : Symbol(f02, Decl(destructuringWithLiteralInitializers2.ts, 1, 28)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 2, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 2, 16)) + +function f03([x, y] = [1, 'foo']) {} +>f03 : Symbol(f03, Decl(destructuringWithLiteralInitializers2.ts, 2, 29)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 3, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 3, 16)) + +function f10([x = 0, y]) {} +>f10 : Symbol(f10, Decl(destructuringWithLiteralInitializers2.ts, 3, 36)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 5, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 5, 20)) + +function f11([x = 0, y] = []) {} +>f11 : Symbol(f11, Decl(destructuringWithLiteralInitializers2.ts, 5, 27)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 6, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 6, 20)) + +function f12([x = 0, y] = [1]) {} +>f12 : Symbol(f12, Decl(destructuringWithLiteralInitializers2.ts, 6, 32)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 7, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 7, 20)) + +function f13([x = 0, y] = [1, 'foo']) {} +>f13 : Symbol(f13, Decl(destructuringWithLiteralInitializers2.ts, 7, 33)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 8, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 8, 20)) + +function f20([x = 0, y = 'bar']) {} +>f20 : Symbol(f20, Decl(destructuringWithLiteralInitializers2.ts, 8, 40)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 10, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 10, 20)) + +function f21([x = 0, y = 'bar'] = []) {} +>f21 : Symbol(f21, Decl(destructuringWithLiteralInitializers2.ts, 10, 35)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 11, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 11, 20)) + +function f22([x = 0, y = 'bar'] = [1]) {} +>f22 : Symbol(f22, Decl(destructuringWithLiteralInitializers2.ts, 11, 40)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 12, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 12, 20)) + +function f23([x = 0, y = 'bar'] = [1, 'foo']) {} +>f23 : Symbol(f23, Decl(destructuringWithLiteralInitializers2.ts, 12, 41)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 13, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 13, 20)) + +declare const nx: number | undefined; +>nx : Symbol(nx, Decl(destructuringWithLiteralInitializers2.ts, 15, 13)) + +declare const sx: string | undefined; +>sx : Symbol(sx, Decl(destructuringWithLiteralInitializers2.ts, 16, 13)) + +function f30([x = 0, y = 'bar']) {} +>f30 : Symbol(f30, Decl(destructuringWithLiteralInitializers2.ts, 16, 37)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 18, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 18, 20)) + +function f31([x = 0, y = 'bar'] = []) {} +>f31 : Symbol(f31, Decl(destructuringWithLiteralInitializers2.ts, 18, 35)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 19, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 19, 20)) + +function f32([x = 0, y = 'bar'] = [nx]) {} +>f32 : Symbol(f32, Decl(destructuringWithLiteralInitializers2.ts, 19, 40)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 20, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 20, 20)) +>nx : Symbol(nx, Decl(destructuringWithLiteralInitializers2.ts, 15, 13)) + +function f33([x = 0, y = 'bar'] = [nx, sx]) {} +>f33 : Symbol(f33, Decl(destructuringWithLiteralInitializers2.ts, 20, 42)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 21, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 21, 20)) +>nx : Symbol(nx, Decl(destructuringWithLiteralInitializers2.ts, 15, 13)) +>sx : Symbol(sx, Decl(destructuringWithLiteralInitializers2.ts, 16, 13)) + +function f40([x = 0, y = 'bar']) {} +>f40 : Symbol(f40, Decl(destructuringWithLiteralInitializers2.ts, 21, 46)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 23, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 23, 20)) + +function f41([x = 0, y = 'bar'] = []) {} +>f41 : Symbol(f41, Decl(destructuringWithLiteralInitializers2.ts, 23, 35)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 24, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 24, 20)) + +function f42([x = 0, y = 'bar'] = [sx]) {} +>f42 : Symbol(f42, Decl(destructuringWithLiteralInitializers2.ts, 24, 40)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 25, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 25, 20)) +>sx : Symbol(sx, Decl(destructuringWithLiteralInitializers2.ts, 16, 13)) + +function f43([x = 0, y = 'bar'] = [sx, nx]) {} +>f43 : Symbol(f43, Decl(destructuringWithLiteralInitializers2.ts, 25, 42)) +>x : Symbol(x, Decl(destructuringWithLiteralInitializers2.ts, 26, 14)) +>y : Symbol(y, Decl(destructuringWithLiteralInitializers2.ts, 26, 20)) +>sx : Symbol(sx, Decl(destructuringWithLiteralInitializers2.ts, 16, 13)) +>nx : Symbol(nx, Decl(destructuringWithLiteralInitializers2.ts, 15, 13)) + diff --git a/tests/baselines/reference/destructuringWithLiteralInitializers2.types b/tests/baselines/reference/destructuringWithLiteralInitializers2.types new file mode 100644 index 0000000000000..7f955912e74d8 --- /dev/null +++ b/tests/baselines/reference/destructuringWithLiteralInitializers2.types @@ -0,0 +1,165 @@ +=== tests/cases/conformance/es6/destructuring/destructuringWithLiteralInitializers2.ts === +function f00([x, y]) {} +>f00 : ([x, y]: [any, any]) => void +>x : any +>y : any + +function f01([x, y] = []) {} +>f01 : ([x, y]?: [any?, any?]) => void +>x : any +>y : any +>[] : [] + +function f02([x, y] = [1]) {} +>f02 : ([x, y]?: [number, any?]) => void +>x : number +>y : any +>[1] : [number] +>1 : 1 + +function f03([x, y] = [1, 'foo']) {} +>f03 : ([x, y]?: [number, string]) => void +>x : number +>y : string +>[1, 'foo'] : [number, string] +>1 : 1 +>'foo' : "foo" + +function f10([x = 0, y]) {} +>f10 : ([x, y]: [number | undefined, any]) => void +>x : number +>0 : 0 +>y : any + +function f11([x = 0, y] = []) {} +>f11 : ([x, y]?: [(number | undefined)?, any?]) => void +>x : number +>0 : 0 +>y : any +>[] : [] + +function f12([x = 0, y] = [1]) {} +>f12 : ([x, y]?: [number, any?]) => void +>x : number +>0 : 0 +>y : any +>[1] : [number] +>1 : 1 + +function f13([x = 0, y] = [1, 'foo']) {} +>f13 : ([x, y]?: [number, string]) => void +>x : number +>0 : 0 +>y : string +>[1, 'foo'] : [number, string] +>1 : 1 +>'foo' : "foo" + +function f20([x = 0, y = 'bar']) {} +>f20 : ([x, y]: [(number | undefined)?, (string | undefined)?]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" + +function f21([x = 0, y = 'bar'] = []) {} +>f21 : ([x, y]?: [(number | undefined)?, (string | undefined)?]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" +>[] : [] + +function f22([x = 0, y = 'bar'] = [1]) {} +>f22 : ([x, y]?: [number, (string | undefined)?]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" +>[1] : [number] +>1 : 1 + +function f23([x = 0, y = 'bar'] = [1, 'foo']) {} +>f23 : ([x, y]?: [number, string]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" +>[1, 'foo'] : [number, string] +>1 : 1 +>'foo' : "foo" + +declare const nx: number | undefined; +>nx : number | undefined + +declare const sx: string | undefined; +>sx : string | undefined + +function f30([x = 0, y = 'bar']) {} +>f30 : ([x, y]: [(number | undefined)?, (string | undefined)?]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" + +function f31([x = 0, y = 'bar'] = []) {} +>f31 : ([x, y]?: [(number | undefined)?, (string | undefined)?]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" +>[] : [] + +function f32([x = 0, y = 'bar'] = [nx]) {} +>f32 : ([x, y]?: [number | undefined, (string | undefined)?]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" +>[nx] : [number | undefined] +>nx : number | undefined + +function f33([x = 0, y = 'bar'] = [nx, sx]) {} +>f33 : ([x, y]?: [number | undefined, string | undefined]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" +>[nx, sx] : [number | undefined, string | undefined] +>nx : number | undefined +>sx : string | undefined + +function f40([x = 0, y = 'bar']) {} +>f40 : ([x, y]: [(number | undefined)?, (string | undefined)?]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" + +function f41([x = 0, y = 'bar'] = []) {} +>f41 : ([x, y]?: [(number | undefined)?, (string | undefined)?]) => void +>x : number +>0 : 0 +>y : string +>'bar' : "bar" +>[] : [] + +function f42([x = 0, y = 'bar'] = [sx]) {} +>f42 : ([x, y]?: [string | undefined, (string | undefined)?]) => void +>x : string | number +>0 : 0 +>y : string +>'bar' : "bar" +>[sx] : [string | undefined] +>sx : string | undefined + +function f43([x = 0, y = 'bar'] = [sx, nx]) {} +>f43 : ([x, y]?: [string | undefined, number | undefined]) => void +>x : string | number +>0 : 0 +>y : string | number +>'bar' : "bar" +>[sx, nx] : [string | undefined, number | undefined] +>sx : string | undefined +>nx : number | undefined + From 17153a6e5fb6bc34422a460b4d0246afd4cc0dd2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 30 Jun 2019 08:54:48 -1000 Subject: [PATCH 9/9] Fix linting error --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 533231a575be5..9c7a538172cef 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24259,7 +24259,7 @@ namespace ts { const elementTypes = arity ? type.typeArguments!.slice() : []; for (let i = arity; i < patternElements.length; i++) { const e = patternElements[i]; - if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && (e).dotDotDotToken)) { + if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && e.dotDotDotToken)) { elementTypes.push(!isOmittedExpression(e) && hasDefaultValue(e) ? getTypeFromBindingElement(e, /*includePatternInType*/ false, /*reportErrors*/ false) : anyType); if (!isOmittedExpression(e) && !hasDefaultValue(e)) { reportImplicitAny(e, anyType);