Proper treatment of splicing tuples in array literals

Fixes #32465.

After this was done, I continued to extend the implementation to handle
TupleLike types but it'ss broken since JS doesn't allow splicing
TupleLike values into array literals so pulled that out, and instead
keeping it for reference below.  (It Includes tests, which are broken
too.)

modified   src/compiler/checker.ts
@@ -22268,6 +22268,21 @@ namespace ts {
                         else hasNonEndingSpreadElement = true;
                     }
                 }
+                else if (spreadType && isTupleLikeType(spreadType)) {
+                    let i = 0, tupleEltType: Type | undefined;
+                    while (tupleEltType = getTypeOfPropertyOfType(spreadType, "" + i as __String)) {
+                        elementTypes.push(tupleEltType);
+                        i++;
+                    }
+                    const stringIndexInfo = getIndexInfoOfType(spreadType, IndexKind.String);
+                    const numberIndexInfo = getIndexInfoOfType(spreadType, IndexKind.Number);
+                    if (stringIndexInfo || numberIndexInfo) {
+                        if (stringIndexInfo) elementTypes.push(stringIndexInfo.type);
+                        if (numberIndexInfo) elementTypes.push(numberIndexInfo.type);
+                        if (i === elementCount - 1) hasEndingSpreadElement = true;
+                        else hasNonEndingSpreadElement = true;
+                    }
+                }
                 else {
                     if (inDestructuringPattern && spreadType) {
                         // Given the following situation:
new file   tests/cases/compiler/spliceTupleLikesWIntegers.ts
@@ -0,0 +1,23 @@
+declare const sb: { [0]: string, [1]: boolean };
+
+let k1: [number, string, boolean];
+k1 = [1, ...sb];
+
+let k2: [number, string, boolean, number];
+k2 = [1, ...sb, 1];
+
+// declare const sb_: [string, ...boolean[]];
+
+// let k3: [number, string, ...boolean[]];
+// k3 = [1, ...sb_];
+
+// declare const sbb_: [string, boolean, ...boolean[]];
+
+// let k4: [number, string, ...boolean[]];
+// k4 = [1, ...sbb_];
+
+// let k5: [number, string, boolean, ...boolean[]];
+// k5 = [1, ...sbb_];
+
+// let k6: [number, string, boolean, boolean, ...boolean[]];
+// k6 = [1, ...sbb_];
new file   tests/cases/compiler/spliceTupleLikesWStrings.ts
@@ -0,0 +1,23 @@
+declare const sb: { 0: string, 1: boolean };
+
+let k1: [number, string, boolean];
+k1 = [1, ...sb];
+
+let k2: [number, string, boolean, number];
+k2 = [1, ...sb, 1];
+
+declare const sb_: { 0: string, [s: string]: (boolean|string) };
+
+let k3: [number, string, ...(boolean|string)[]];
+k3 = [1, ...sb_];
+
+declare const sbb_: { 0: string, 1: boolean, [s: string]: (boolean|string) };
+
+let k4: [number, string, boolean, ...(boolean|string)[]];
+k4 = [1, ...sbb_];
+
+// let k5: [number, string, boolean, ...(boolean|string)[]];
+// k5 = [1, ...sbb_];
+
+// let k6: [number, string, boolean, boolean, ...(boolean|string)[]];
+// k6 = [1, ...sbb_];
This commit is contained in:
Eli Barzilay 2020-02-13 16:09:20 -05:00
parent 6c5c48c74c
commit e71614a185
21 changed files with 307 additions and 88 deletions

View file

@ -17226,7 +17226,7 @@ namespace ts {
/**
* Check if a Type was written as a tuple type literal.
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
* Prefer using isTupleLikeType() unless the use of `elementTypes`/`getTypeArguments` is required.
*/
function isTupleType(type: Type): type is TupleTypeReference {
return !!(getObjectFlags(type) & ObjectFlags.Reference && (<TypeReference>type).target.objectFlags & ObjectFlags.Tuple);
@ -22290,58 +22290,69 @@ namespace ts {
function checkArrayLiteral(node: ArrayLiteralExpression, checkMode: CheckMode | undefined, forceTuple: boolean | undefined): Type {
const elements = node.elements;
const elementCount = elements.length;
let hasNonEndingSpreadElement = false;
const elementTypes: Type[] = [];
const inDestructuringPattern = isAssignmentTarget(node);
let hasEndingSpreadElement = false;
let hasNonEndingSpreadElement = false;
const contextualType = getApparentTypeOfContextualType(node);
const inDestructuringPattern = isAssignmentTarget(node);
const inConstContext = isConstContext(node);
for (let index = 0; index < elementCount; index++) {
const e = elements[index];
if (inDestructuringPattern && e.kind === SyntaxKind.SpreadElement) {
// Given the following situation:
// var c: {};
// [...c] = ["", 0];
//
// c is represented in the tree as a spread element in an array literal.
// But c really functions as a rest element, and its purpose is to provide
// a contextual type for the right hand side of the assignment. Therefore,
// instead of calling checkExpression on "...c", which will give an error
// if c is not iterable/array-like, we need to act as if we are trying to
// get the contextual element type from it. So we do something similar to
// getContextualTypeForElementExpression, which will crucially not error
// if there is no index type / iterated type.
const restArrayType = checkExpression((<SpreadElement>e).expression, checkMode, forceTuple);
const restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) ||
getIteratedTypeOrElementType(IterationUse.Destructuring, restArrayType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false);
if (restElementType) {
elementTypes.push(restElementType);
for (let i = 0; i < elementCount; i++) {
const e = elements[i];
const spread = e.kind === SyntaxKind.SpreadElement && (<SpreadElement>e).expression;
const spreadType = spread && checkExpression(spread, checkMode, forceTuple);
if (spreadType && isTupleType(spreadType)) {
elementTypes.push(...getTypeArguments(spreadType));
if (spreadType.target.hasRestElement) {
if (i === elementCount - 1) hasEndingSpreadElement = true;
else hasNonEndingSpreadElement = true;
}
}
else {
const elementContextualType = getContextualTypeForElementExpression(contextualType, index);
const type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple);
elementTypes.push(type);
}
if (index < elementCount - 1 && e.kind === SyntaxKind.SpreadElement) {
hasNonEndingSpreadElement = true;
if (inDestructuringPattern && spreadType) {
// Given the following situation:
// var c: {};
// [...c] = ["", 0];
//
// c is represented in the tree as a spread element in an array literal.
// But c really functions as a rest element, and its purpose is to provide
// a contextual type for the right hand side of the assignment. Therefore,
// instead of calling checkExpression on "...c", which will give an error
// if c is not iterable/array-like, we need to act as if we are trying to
// get the contextual element type from it. So we do something similar to
// getContextualTypeForElementExpression, which will crucially not error
// if there is no index type / iterated type.
const restElementType = getIndexTypeOfType(spreadType, IndexKind.Number) ||
getIteratedTypeOrElementType(IterationUse.Destructuring, spreadType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false);
if (restElementType) {
elementTypes.push(restElementType);
}
}
else {
const elementContextualType = getContextualTypeForElementExpression(contextualType, elementTypes.length);
const type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple);
elementTypes.push(type);
}
if (spread) { // tuples are done above, so these are only arrays
if (i === elementCount - 1) hasEndingSpreadElement = true;
else hasNonEndingSpreadElement = true;
}
}
}
if (!hasNonEndingSpreadElement) {
const hasRestElement = elementCount > 0 && elements[elementCount - 1].kind === SyntaxKind.SpreadElement;
const minLength = elementCount - (hasRestElement ? 1 : 0);
const minLength = elementTypes.length - (hasEndingSpreadElement ? 1 : 0);
// If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
// that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
let tupleResult;
if (inDestructuringPattern && minLength > 0) {
const type = cloneTypeReference(<TypeReference>createTupleType(elementTypes, minLength, hasRestElement));
const type = cloneTypeReference(<TypeReference>createTupleType(elementTypes, minLength, hasEndingSpreadElement));
type.pattern = node;
return type;
}
else if (tupleResult = getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasRestElement, elementCount, inConstContext)) {
else if (tupleResult = getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasEndingSpreadElement, elementTypes.length, inConstContext)) {
return createArrayLiteralType(tupleResult);
}
else if (forceTuple) {
return createArrayLiteralType(createTupleType(elementTypes, minLength, hasRestElement));
return createArrayLiteralType(createTupleType(elementTypes, minLength, hasEndingSpreadElement));
}
}
return createArrayLiteralType(createArrayType(elementTypes.length ?

View file

@ -7,9 +7,9 @@ tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionConte
tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(8,5): error TS2322: Type '[number, number, number, string]' is not assignable to type '[number, number, number]'.
Types of property 'length' are incompatible.
Type '4' is not assignable to type '3'.
tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(14,5): error TS2322: Type '[number, number, number, ...number[]]' is not assignable to type '[number, number, number]'.
tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(14,5): error TS2322: Type '[number, number, number, number, number, number]' is not assignable to type '[number, number, number]'.
Types of property 'length' are incompatible.
Type 'number' is not assignable to type '3'.
Type '6' is not assignable to type '3'.
==== tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts (4 errors) ====
@ -40,7 +40,7 @@ tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionConte
var spr1 = [1, 2, 3, ...tup];
var spr2:[number, number, number] = [1, 2, 3, ...tup]; // Error
~~~~
!!! error TS2322: Type '[number, number, number, ...number[]]' is not assignable to type '[number, number, number]'.
!!! error TS2322: Type '[number, number, number, number, number, number]' is not assignable to type '[number, number, number]'.
!!! error TS2322: Types of property 'length' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type '3'.
!!! error TS2322: Type '6' is not assignable to type '3'.

View file

@ -62,7 +62,7 @@ var spr1 = [1, 2, 3, ...tup];
var spr2:[number, number, number] = [1, 2, 3, ...tup]; // Error
>spr2 : [number, number, number]
>[1, 2, 3, ...tup] : [number, number, number, ...number[]]
>[1, 2, 3, ...tup] : [number, number, number, number, number, number]
>1 : 1
>2 : 2
>3 : 3

View file

@ -5,7 +5,6 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(11,51): erro
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(17,5): error TS2322: Type '[number, number, string, boolean]' is not assignable to type '[number, number]'.
Types of property 'length' are incompatible.
Type '4' is not assignable to type '2'.
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(32,5): error TS2739: Type '(number[] | string[])[]' is missing the following properties from type 'tup': 0, 1
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(33,5): error TS2739: Type 'number[]' is missing the following properties from type '[number, number, number]': 0, 1, 2
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error TS2322: Type '(string | number)[]' is not assignable to type 'myArray'.
The types returned by 'pop()' are incompatible between these types.
@ -13,7 +12,7 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error
Type 'string' is not assignable to type 'Number'.
==== tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts (8 errors) ====
==== tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts (7 errors) ====
// Each element expression in a non-empty array literal is processed as follows:
// - If the array literal contains no spread elements, and if the array literal is contextually typed (section 4.19)
// by a type T and T has a property with the numeric name N, where N is the index of the element expression in the array literal,
@ -58,8 +57,6 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error
interface myArray extends Array<Number> { }
interface myArray2 extends Array<Number|String> { }
var c0: tup = [...temp2]; // Error
~~
!!! error TS2739: Type '(number[] | string[])[]' is missing the following properties from type 'tup': 0, 1
var c1: [number, number, number] = [...temp1]; // Error cannot assign number[] to [number, number, number]
~~
!!! error TS2739: Type 'number[]' is missing the following properties from type '[number, number, number]': 0, 1, 2

View file

@ -71,7 +71,7 @@ interface myArray extends Array<Number> { }
interface myArray2 extends Array<Number|String> { }
var c0: tup = [...temp2]; // Error
>c0 : tup
>[...temp2] : (number[] | string[])[]
>[...temp2] : [number[], string[]]
>...temp2 : number[] | string[]
>temp2 : [number[], string[]]

View file

@ -143,7 +143,7 @@ declare let vc1: "abc";
declare let a1: readonly [];
declare let a2: readonly [1, 2, 3];
declare let a3: readonly [10, "hello", true];
declare let a4: readonly (1 | 2 | 3)[];
declare let a4: readonly [1, 2, 3];
declare let a5: number[];
declare let a6: readonly number[];
declare let a7: number[];

View file

@ -125,9 +125,9 @@ let a3 = [10, 'hello', true] as const;
>true : true
let a4 = [...[1, 2, 3]] as const;
>a4 : readonly (1 | 2 | 3)[]
>[...[1, 2, 3]] as const : readonly (1 | 2 | 3)[]
>[...[1, 2, 3]] : readonly (1 | 2 | 3)[]
>a4 : readonly [1, 2, 3]
>[...[1, 2, 3]] as const : readonly [1, 2, 3]
>[...[1, 2, 3]] : readonly [1, 2, 3]
>...[1, 2, 3] : 1 | 2 | 3
>[1, 2, 3] : readonly [1, 2, 3]
>1 : 1

View file

@ -727,14 +727,14 @@ function f20(v: [number, number, number]) {
[...a3] = v;
>[...a3] = v : [number, number, number]
>[...a3] : number[]
>[...a3] : [number, number, number]
>...a3 : number
>a3 : [number, number, number]
>v : [number, number, number]
[x, ...a2] = v;
>[x, ...a2] = v : [number, number, number]
>[x, ...a2] : [number, ...number[]]
>[x, ...a2] : [number, number, number]
>x : number
>...a2 : number
>a2 : [number, number]
@ -742,7 +742,7 @@ function f20(v: [number, number, number]) {
[x, y, ...a1] = v;
>[x, y, ...a1] = v : [number, number, number]
>[x, y, ...a1] : [number, number, ...number[]]
>[x, y, ...a1] : [number, number, number]
>x : number
>y : number
>...a1 : number
@ -751,7 +751,7 @@ function f20(v: [number, number, number]) {
[x, y, z, ...a0] = v;
>[x, y, z, ...a0] = v : [number, number, number]
>[x, y, z, ...a0] : [number, number, number, ...never[]]
>[x, y, z, ...a0] : [number, number, number]
>x : number
>y : number
>z : number
@ -809,14 +809,14 @@ function f21(v: [number, string, boolean]) {
[...a0] = v;
>[...a0] = v : [number, string, boolean]
>[...a0] : (string | number | boolean)[]
>[...a0] : [number, string, boolean]
>...a0 : string | number | boolean
>a0 : [number, string, boolean]
>v : [number, string, boolean]
[x, ...a1] = v;
>[x, ...a1] = v : [number, string, boolean]
>[x, ...a1] : [number, ...(string | boolean)[]]
>[x, ...a1] : [number, string, boolean]
>x : number
>...a1 : string | boolean
>a1 : [string, boolean]
@ -824,7 +824,7 @@ function f21(v: [number, string, boolean]) {
[x, y, ...a2] = v;
>[x, y, ...a2] = v : [number, string, boolean]
>[x, y, ...a2] : [number, string, ...boolean[]]
>[x, y, ...a2] : [number, string, boolean]
>x : number
>y : string
>...a2 : boolean
@ -833,7 +833,7 @@ function f21(v: [number, string, boolean]) {
[x, y, z, ...a3] = v;
>[x, y, z, ...a3] = v : [number, string, boolean]
>[x, y, z, ...a3] : [number, string, boolean, ...never[]]
>[x, y, z, ...a3] : [number, string, boolean]
>x : number
>y : string
>z : boolean

View file

@ -15,7 +15,7 @@ declare var receiver: typeof tuple;
[...receiver] = tuple;
>[...receiver] = tuple : [boolean, number, ...string[]]
>[...receiver] : (string | number | boolean)[]
>[...receiver] : [boolean, number, ...string[]]
>...receiver : string | number | boolean
>receiver : [boolean, number, ...string[]]
>tuple : [boolean, number, ...string[]]

View file

@ -13,7 +13,7 @@ var map = new Map([["", true]]);
>true : true
for ([k, ...[v]] of map) {
>[k, ...[v]] : [string, ...boolean[]]
>[k, ...[v]] : [string, boolean]
>k : string
>...[v] : boolean
>[v] : [boolean]

View file

@ -1,6 +1,5 @@
tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts(37,5): error TS2322: Type '"y"' is not assignable to type '"x"'.
tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts(60,5): error TS2322: Type 'string[]' is not assignable to type 'XY[]'.
Type 'string' is not assignable to type 'XY'.
tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts(60,12): error TS2322: Type 'string' is not assignable to type 'XY'.
==== tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts (2 errors) ====
@ -66,7 +65,6 @@ tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts(60,5): error TS23
// Desired: OK
// Error in all extant branches
arr = [...['y']];
~~~
!!! error TS2322: Type 'string[]' is not assignable to type 'XY[]'.
!!! error TS2322: Type 'string' is not assignable to type 'XY'.
~~~~~~~~
!!! error TS2322: Type 'string' is not assignable to type 'XY'.
}

View file

@ -8,12 +8,12 @@ var [...a, x] = [1, 2, 3]; // Error, rest must be last element
>3 : 3
[...a, x] = [1, 2, 3]; // Error, rest must be last element
>[...a, x] = [1, 2, 3] : number[]
>[...a, x] : number[]
>[...a, x] = [1, 2, 3] : [number, number, number]
>[...a, x] : [number, number, number, number]
>...a : number
>a : [number, number, number]
>x : number
>[1, 2, 3] : number[]
>[1, 2, 3] : [number, number, number]
>1 : 1
>2 : 2
>3 : 3

View file

@ -1,15 +0,0 @@
tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern1.ts(2,6): error TS2322: Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern1.ts(2,9): error TS2322: Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
==== tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern1.ts (2 errors) ====
var a: string, b: number;
[...[a, b = 0]] = ["", 1];
~
!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
~
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.

View file

@ -4,15 +4,15 @@ var a: string, b: number;
>b : number
[...[a, b = 0]] = ["", 1];
>[...[a, b = 0]] = ["", 1] : (string | number)[]
>[...[a, b = 0]] : (string | number)[]
>[...[a, b = 0]] = ["", 1] : [string, number]
>[...[a, b = 0]] : [string, number]
>...[a, b = 0] : string | number
>[a, b = 0] : [string, number]
>a : string
>b = 0 : 0
>b : number
>0 : 0
>["", 1] : (string | number)[]
>["", 1] : [string, number]
>"" : ""
>1 : 1

View file

@ -11,7 +11,7 @@ var tuple: [string, number] = ["", 1];
[...[a, b = 0]] = tuple;
>[...[a, b = 0]] = tuple : [string, number]
>[...[a, b = 0]] : (string | number)[]
>[...[a, b = 0]] : [string, number]
>...[a, b = 0] : string | number
>[a, b = 0] : [string, number]
>a : string

View file

@ -4,13 +4,13 @@ var s: string, s2: string;
>s2 : string
[...[s, s2]] = ["", ""];
>[...[s, s2]] = ["", ""] : string[]
>[...[s, s2]] : string[]
>[...[s, s2]] = ["", ""] : [string, string]
>[...[s, s2]] : [string, string]
>...[s, s2] : string
>[s, s2] : [string, string]
>s : string
>s2 : string
>["", ""] : string[]
>["", ""] : [string, string]
>"" : ""
>"" : ""

View file

@ -0,0 +1,30 @@
tests/cases/compiler/spliceTuples.ts(23,1): error TS2741: Property '3' is missing in type '[number, string, boolean, ...boolean[]]' but required in type '[number, string, boolean, boolean, ...boolean[]]'.
==== tests/cases/compiler/spliceTuples.ts (1 errors) ====
declare const sb: [string, boolean];
let k1: [number, string, boolean];
k1 = [1, ...sb];
let k2: [number, string, boolean, number];
k2 = [1, ...sb, 1];
declare const sb_: [string, ...boolean[]];
let k3: [number, string, ...boolean[]];
k3 = [1, ...sb_];
declare const sbb_: [string, boolean, ...boolean[]];
let k4: [number, string, ...boolean[]];
k4 = [1, ...sbb_];
let k5: [number, string, boolean, ...boolean[]];
k5 = [1, ...sbb_];
let k6: [number, string, boolean, boolean, ...boolean[]];
k6 = [1, ...sbb_];
~~
!!! error TS2741: Property '3' is missing in type '[number, string, boolean, ...boolean[]]' but required in type '[number, string, boolean, boolean, ...boolean[]]'.

View file

@ -0,0 +1,46 @@
//// [spliceTuples.ts]
declare const sb: [string, boolean];
let k1: [number, string, boolean];
k1 = [1, ...sb];
let k2: [number, string, boolean, number];
k2 = [1, ...sb, 1];
declare const sb_: [string, ...boolean[]];
let k3: [number, string, ...boolean[]];
k3 = [1, ...sb_];
declare const sbb_: [string, boolean, ...boolean[]];
let k4: [number, string, ...boolean[]];
k4 = [1, ...sbb_];
let k5: [number, string, boolean, ...boolean[]];
k5 = [1, ...sbb_];
let k6: [number, string, boolean, boolean, ...boolean[]];
k6 = [1, ...sbb_];
//// [spliceTuples.js]
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
var k1;
k1 = __spreadArrays([1], sb);
var k2;
k2 = __spreadArrays([1], sb, [1]);
var k3;
k3 = __spreadArrays([1], sb_);
var k4;
k4 = __spreadArrays([1], sbb_);
var k5;
k5 = __spreadArrays([1], sbb_);
var k6;
k6 = __spreadArrays([1], sbb_);

View file

@ -0,0 +1,52 @@
=== tests/cases/compiler/spliceTuples.ts ===
declare const sb: [string, boolean];
>sb : Symbol(sb, Decl(spliceTuples.ts, 0, 13))
let k1: [number, string, boolean];
>k1 : Symbol(k1, Decl(spliceTuples.ts, 2, 3))
k1 = [1, ...sb];
>k1 : Symbol(k1, Decl(spliceTuples.ts, 2, 3))
>sb : Symbol(sb, Decl(spliceTuples.ts, 0, 13))
let k2: [number, string, boolean, number];
>k2 : Symbol(k2, Decl(spliceTuples.ts, 5, 3))
k2 = [1, ...sb, 1];
>k2 : Symbol(k2, Decl(spliceTuples.ts, 5, 3))
>sb : Symbol(sb, Decl(spliceTuples.ts, 0, 13))
declare const sb_: [string, ...boolean[]];
>sb_ : Symbol(sb_, Decl(spliceTuples.ts, 8, 13))
let k3: [number, string, ...boolean[]];
>k3 : Symbol(k3, Decl(spliceTuples.ts, 10, 3))
k3 = [1, ...sb_];
>k3 : Symbol(k3, Decl(spliceTuples.ts, 10, 3))
>sb_ : Symbol(sb_, Decl(spliceTuples.ts, 8, 13))
declare const sbb_: [string, boolean, ...boolean[]];
>sbb_ : Symbol(sbb_, Decl(spliceTuples.ts, 13, 13))
let k4: [number, string, ...boolean[]];
>k4 : Symbol(k4, Decl(spliceTuples.ts, 15, 3))
k4 = [1, ...sbb_];
>k4 : Symbol(k4, Decl(spliceTuples.ts, 15, 3))
>sbb_ : Symbol(sbb_, Decl(spliceTuples.ts, 13, 13))
let k5: [number, string, boolean, ...boolean[]];
>k5 : Symbol(k5, Decl(spliceTuples.ts, 18, 3))
k5 = [1, ...sbb_];
>k5 : Symbol(k5, Decl(spliceTuples.ts, 18, 3))
>sbb_ : Symbol(sbb_, Decl(spliceTuples.ts, 13, 13))
let k6: [number, string, boolean, boolean, ...boolean[]];
>k6 : Symbol(k6, Decl(spliceTuples.ts, 21, 3))
k6 = [1, ...sbb_];
>k6 : Symbol(k6, Decl(spliceTuples.ts, 21, 3))
>sbb_ : Symbol(sbb_, Decl(spliceTuples.ts, 13, 13))

View file

@ -0,0 +1,77 @@
=== tests/cases/compiler/spliceTuples.ts ===
declare const sb: [string, boolean];
>sb : [string, boolean]
let k1: [number, string, boolean];
>k1 : [number, string, boolean]
k1 = [1, ...sb];
>k1 = [1, ...sb] : [number, string, boolean]
>k1 : [number, string, boolean]
>[1, ...sb] : [number, string, boolean]
>1 : 1
>...sb : string | boolean
>sb : [string, boolean]
let k2: [number, string, boolean, number];
>k2 : [number, string, boolean, number]
k2 = [1, ...sb, 1];
>k2 = [1, ...sb, 1] : [number, string, boolean, number]
>k2 : [number, string, boolean, number]
>[1, ...sb, 1] : [number, string, boolean, number]
>1 : 1
>...sb : string | boolean
>sb : [string, boolean]
>1 : 1
declare const sb_: [string, ...boolean[]];
>sb_ : [string, ...boolean[]]
let k3: [number, string, ...boolean[]];
>k3 : [number, string, ...boolean[]]
k3 = [1, ...sb_];
>k3 = [1, ...sb_] : [number, string, ...boolean[]]
>k3 : [number, string, ...boolean[]]
>[1, ...sb_] : [number, string, ...boolean[]]
>1 : 1
>...sb_ : string | boolean
>sb_ : [string, ...boolean[]]
declare const sbb_: [string, boolean, ...boolean[]];
>sbb_ : [string, boolean, ...boolean[]]
let k4: [number, string, ...boolean[]];
>k4 : [number, string, ...boolean[]]
k4 = [1, ...sbb_];
>k4 = [1, ...sbb_] : [number, string, boolean, ...boolean[]]
>k4 : [number, string, ...boolean[]]
>[1, ...sbb_] : [number, string, boolean, ...boolean[]]
>1 : 1
>...sbb_ : string | boolean
>sbb_ : [string, boolean, ...boolean[]]
let k5: [number, string, boolean, ...boolean[]];
>k5 : [number, string, boolean, ...boolean[]]
k5 = [1, ...sbb_];
>k5 = [1, ...sbb_] : [number, string, boolean, ...boolean[]]
>k5 : [number, string, boolean, ...boolean[]]
>[1, ...sbb_] : [number, string, boolean, ...boolean[]]
>1 : 1
>...sbb_ : string | boolean
>sbb_ : [string, boolean, ...boolean[]]
let k6: [number, string, boolean, boolean, ...boolean[]];
>k6 : [number, string, boolean, boolean, ...boolean[]]
k6 = [1, ...sbb_];
>k6 = [1, ...sbb_] : [number, string, boolean, ...boolean[]]
>k6 : [number, string, boolean, boolean, ...boolean[]]
>[1, ...sbb_] : [number, string, boolean, ...boolean[]]
>1 : 1
>...sbb_ : string | boolean
>sbb_ : [string, boolean, ...boolean[]]

View file

@ -0,0 +1,23 @@
declare const sb: [string, boolean];
let k1: [number, string, boolean];
k1 = [1, ...sb];
let k2: [number, string, boolean, number];
k2 = [1, ...sb, 1];
declare const sb_: [string, ...boolean[]];
let k3: [number, string, ...boolean[]];
k3 = [1, ...sb_];
declare const sbb_: [string, boolean, ...boolean[]];
let k4: [number, string, ...boolean[]];
k4 = [1, ...sbb_];
let k5: [number, string, boolean, ...boolean[]];
k5 = [1, ...sbb_];
let k6: [number, string, boolean, boolean, ...boolean[]];
k6 = [1, ...sbb_];