Merge pull request #27587 from Microsoft/fixUnionOfTupleIndexing

Fix indexing and destructuring of unions of tuple types
This commit is contained in:
Anders Hejlsberg
2018-10-11 12:01:24 -07:00
committed by GitHub
40 changed files with 2183 additions and 1453 deletions
+32 -33
View File
@@ -4705,14 +4705,14 @@ namespace ts {
// If the parent is a tuple type, the rest element has a tuple type of the
// remaining tuple element types. Otherwise, the rest element has an array type with same
// element type as the parent type.
type = isTupleType(parentType) ?
sliceTupleType(parentType, index) :
type = everyType(parentType, isTupleType) ?
mapType(parentType, t => sliceTupleType(<TupleTypeReference>t, index)) :
createArrayType(elementType);
}
else {
// Use specific property type when parent is a tuple or numeric index type when parent is an array
const index = pattern.elements.indexOf(declaration);
type = isTupleLikeType(parentType) ?
type = everyType(parentType, isTupleLikeType) ?
getTupleElementType(parentType, index) || declaration.initializer && checkDeclarationInitializer(declaration) :
elementType;
if (!type) {
@@ -4728,11 +4728,11 @@ namespace ts {
}
// 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(checkExpressionCached(declaration.initializer)) & TypeFlags.Undefined)) {
if (strictNullChecks && declaration.initializer && !(getFalsyFlags(checkDeclarationInitializer(declaration)) & TypeFlags.Undefined)) {
type = getTypeWithFacts(type, TypeFacts.NEUndefined);
}
return declaration.initializer && !getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration)) ?
getUnionType([type, checkExpressionCached(declaration.initializer)], UnionReduction.Subtype) :
getUnionType([type, checkDeclarationInitializer(declaration)], UnionReduction.Subtype) :
type;
}
@@ -7331,10 +7331,10 @@ namespace ts {
}
}
else if (isUnion) {
const index = !isLateBoundName(name) && ((isNumericLiteralName(name) && getIndexInfoOfType(type, IndexKind.Number)) || getIndexInfoOfType(type, IndexKind.String));
if (index) {
checkFlags |= index.isReadonly ? CheckFlags.Readonly : 0;
indexTypes = append(indexTypes, index.type);
const indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, IndexKind.Number) || getIndexInfoOfType(type, IndexKind.String));
if (indexInfo) {
checkFlags |= indexInfo.isReadonly ? CheckFlags.Readonly : 0;
indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type);
}
else {
checkFlags |= CheckFlags.Partial;
@@ -9342,11 +9342,12 @@ namespace ts {
getFlowTypeOfReference(accessExpression, propType) :
propType;
}
if (isTupleType(objectType)) {
const restType = getRestTypeOfTupleType(objectType);
if (restType && isNumericLiteralName(propName) && +propName >= 0) {
return restType;
if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) {
if (accessNode && everyType(objectType, t => !(<TupleTypeReference>t).target.hasRestElement)) {
const indexNode = accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : accessNode.indexType;
error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType));
}
return mapType(objectType, t => getRestTypeOfTupleType(<TupleTypeReference>t) || undefinedType);
}
}
if (!(indexType.flags & TypeFlags.Nullable) && isTypeAssignableToKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike)) {
@@ -12908,9 +12909,14 @@ namespace ts {
}
function getTupleElementType(type: Type, index: number) {
return isTupleType(type) ?
index < getLengthOfTupleType(type) ? type.typeArguments![index] : getRestTypeOfTupleType(type) :
getTypeOfPropertyOfType(type, "" + index as __String);
const propType = getTypeOfPropertyOfType(type, "" + index as __String);
if (propType) {
return propType;
}
if (everyType(type, isTupleType) && !everyType(type, t => !(<TupleTypeReference>t).target.hasRestElement)) {
return mapType(type, t => getRestTypeOfTupleType(<TupleTypeReference>t) || undefinedType);
}
return undefined;
}
function isNeitherUnitTypeNorNever(type: Type): boolean {
@@ -14402,7 +14408,7 @@ namespace ts {
}
function getTypeOfDestructuredArrayElement(type: Type, index: number) {
return isTupleLikeType(type) && getTupleElementType(type, index) ||
return everyType(type, isTupleLikeType) && getTupleElementType(type, index) ||
checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) ||
errorType;
}
@@ -14600,6 +14606,10 @@ namespace ts {
return type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, f) : f(type);
}
function everyType(type: Type, f: (t: Type) => boolean): boolean {
return type.flags & TypeFlags.Union ? every((<UnionType>type).types, f) : f(type);
}
function filterType(type: Type, f: (t: Type) => boolean): Type {
if (type.flags & TypeFlags.Union) {
const types = (<UnionType>type).types;
@@ -16707,11 +16717,6 @@ namespace ts {
return mapType(type, t => getIndexTypeOfStructuredType(t, kind), /*noReductions*/ true);
}
// Return true if the given contextual type is a tuple-like type
function contextualTypeIsTupleLikeType(type: Type): boolean {
return !!(type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, isTupleLikeType) : isTupleLikeType(type));
}
// In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of
// the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one
// exists. Otherwise, it is the type of the string index signature in T, if one exists.
@@ -17263,7 +17268,8 @@ namespace ts {
}
function getArrayLiteralTupleTypeIfApplicable(elementTypes: Type[], contextualType: Type | undefined, hasRestElement: boolean, elementCount = elementTypes.length) {
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
// Infer a tuple type when the contextual type is or contains a tuple-like type
if (contextualType && forEachType(contextualType, isTupleLikeType)) {
const minLength = elementCount - (hasRestElement ? 1 : 0);
const pattern = contextualType.pattern;
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
@@ -18993,13 +18999,6 @@ namespace ts {
error(indexExpression, Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal);
return errorType;
}
if (isTupleType(objectType) && !objectType.target.hasRestElement && isNumericLiteral(indexExpression)) {
const index = +indexExpression.text;
const maximumIndex = length(objectType.target.typeParameters);
if (index >= maximumIndex) {
error(indexExpression, Diagnostics.Index_0_is_out_of_bounds_in_tuple_of_length_1, index, maximumIndex);
}
}
return checkIndexedAccessIndexType(getIndexedAccessType(objectType, isForInVariableForNumericPropertyNames(indexExpression) ? numberType : indexType, node), node);
}
@@ -21740,7 +21739,7 @@ namespace ts {
if (element.kind !== SyntaxKind.SpreadElement) {
const propName = "" + elementIndex as __String;
const type = isTypeAny(sourceType) ? sourceType :
isTupleLikeType(sourceType) ? getTupleElementType(sourceType, elementIndex) :
everyType(sourceType, isTupleLikeType) ? getTupleElementType(sourceType, elementIndex) :
elementType;
if (type) {
return checkDestructuringAssignment(element, type, checkMode);
@@ -21766,8 +21765,8 @@ namespace ts {
}
else {
checkGrammarForDisallowedTrailingComma(node.elements, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
const type = isTupleType(sourceType) ?
sliceTupleType(sourceType, elementIndex) :
const type = everyType(sourceType, isTupleType) ?
mapType(sourceType, t => sliceTupleType(<TupleTypeReference>t, elementIndex)) :
createArrayType(elementType);
return checkDestructuringAssignment(restExpression, type, checkMode);
}
-4
View File
@@ -2485,10 +2485,6 @@
"category": "Error",
"code": 2732
},
"Index '{0}' is out-of-bounds in tuple of length {1}.": {
"category": "Error",
"code": 2733
},
"It is highly likely that you are missing a semicolon.": {
"category": "Error",
"code": 2734
-17
View File
@@ -36,23 +36,6 @@ namespace ts {
Low = 250
}
function getPriorityValues(highPriorityValue: number): [number, number, number] {
const mediumPriorityValue = highPriorityValue * 2;
const lowPriorityValue = mediumPriorityValue * 4;
return [highPriorityValue, mediumPriorityValue, lowPriorityValue];
}
function pollingInterval(watchPriority: PollingInterval): number {
return pollingIntervalsForPriority[watchPriority];
}
const pollingIntervalsForPriority = getPriorityValues(250);
/* @internal */
export function watchFileUsingPriorityPollingInterval(host: System, fileName: string, callback: FileWatcherCallback, watchPriority: PollingInterval): FileWatcher {
return host.watchFile!(fileName, callback, pollingInterval(watchPriority));
}
/* @internal */
export type HostWatchFile = (fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval | undefined) => FileWatcher;
/* @internal */
@@ -1,7 +1,7 @@
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(22,13): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(23,13): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(24,13): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(25,13): error TS2733: Index '3' is out-of-bounds in tuple of length 3.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(22,13): error TS2339: Property '2' does not exist on type '[(x: number) => string, (x: number) => number]'.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(23,13): error TS2339: Property '2' does not exist on type '[E1, E2]'.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(24,13): error TS2339: Property '2' does not exist on type '[number, any]'.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(25,13): error TS2339: Property '3' does not exist on type '[E1, E2, number]'.
==== tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts (4 errors) ====
@@ -28,13 +28,13 @@ tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfT
t4 = [E1.one, E2.two, 20];
var e1 = t1[2]; // {}
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[(x: number) => string, (x: number) => number]'.
var e2 = t2[2]; // {}
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[E1, E2]'.
var e3 = t3[2]; // any
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[number, any]'.
var e4 = t4[3]; // number
~
!!! error TS2733: Index '3' is out-of-bounds in tuple of length 3.
!!! error TS2339: Property '3' does not exist on type '[E1, E2, number]'.
@@ -76,26 +76,26 @@ t4 = [E1.one, E2.two, 20];
>20 : 20
var e1 = t1[2]; // {}
>e1 : ((x: number) => string) | ((x: number) => number)
>t1[2] : ((x: number) => string) | ((x: number) => number)
>e1 : undefined
>t1[2] : undefined
>t1 : [(x: number) => string, (x: number) => number]
>2 : 2
var e2 = t2[2]; // {}
>e2 : E1 | E2
>t2[2] : E1 | E2
>e2 : undefined
>t2[2] : undefined
>t2 : [E1, E2]
>2 : 2
var e3 = t3[2]; // any
>e3 : any
>t3[2] : any
>e3 : undefined
>t3[2] : undefined
>t3 : [number, any]
>2 : 2
var e4 = t4[3]; // number
>e4 : number
>t4[3] : number
>e4 : undefined
>t4[3] : undefined
>t4 : [E1, E2, number]
>3 : 3
@@ -1,8 +1,8 @@
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(17,14): error TS2733: Index '4' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(18,14): error TS2733: Index '4' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(19,14): error TS2733: Index '4' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(20,14): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(21,14): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(17,14): error TS2339: Property '4' does not exist on type '[C, base]'.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(18,14): error TS2339: Property '4' does not exist on type '[C, D]'.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(19,14): error TS2339: Property '4' does not exist on type '[C1, D1]'.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(20,14): error TS2339: Property '2' does not exist on type '[base1, C1]'.
tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(21,14): error TS2339: Property '2' does not exist on type '[C1, F]'.
==== tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts (5 errors) ====
@@ -24,17 +24,17 @@ tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfT
var e11 = t1[4]; // base
~
!!! error TS2733: Index '4' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '4' does not exist on type '[C, base]'.
var e21 = t2[4]; // {}
~
!!! error TS2733: Index '4' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '4' does not exist on type '[C, D]'.
var e31 = t3[4]; // C1
~
!!! error TS2733: Index '4' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '4' does not exist on type '[C1, D1]'.
var e41 = t4[2]; // base1
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[base1, C1]'.
var e51 = t5[2]; // {}
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[C1, F]'.
@@ -49,32 +49,32 @@ var t5: [C1, F]
>t5 : [C1, F]
var e11 = t1[4]; // base
>e11 : base | C
>t1[4] : base | C
>e11 : undefined
>t1[4] : undefined
>t1 : [C, base]
>4 : 4
var e21 = t2[4]; // {}
>e21 : C | D
>t2[4] : C | D
>e21 : undefined
>t2[4] : undefined
>t2 : [C, D]
>4 : 4
var e31 = t3[4]; // C1
>e31 : C1 | D1
>t3[4] : C1 | D1
>e31 : undefined
>t3[4] : undefined
>t3 : [C1, D1]
>4 : 4
var e41 = t4[2]; // base1
>e41 : base1 | C1
>t4[2] : base1 | C1
>e41 : undefined
>t4[2] : undefined
>t4 : [base1, C1]
>2 : 2
var e51 = t5[2]; // {}
>e51 : F | C1
>t5[2] : F | C1
>e51 : undefined
>t5[2] : undefined
>t5 : [C1, F]
>2 : 2
@@ -6,7 +6,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(14,15): error TS2352: Conver
tests/cases/conformance/types/tuple/castingTuple.ts(15,14): error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
tests/cases/conformance/types/tuple/castingTuple.ts(18,21): error TS2352: Conversion of type '[C, D]' to type '[C, D, A]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Property '2' is missing in type '[C, D]'.
tests/cases/conformance/types/tuple/castingTuple.ts(20,33): error TS2733: Index '5' is out-of-bounds in tuple of length 3.
tests/cases/conformance/types/tuple/castingTuple.ts(20,33): error TS2339: Property '5' does not exist on type '[C, D, A]'.
tests/cases/conformance/types/tuple/castingTuple.ts(30,10): error TS2352: Conversion of type '[number, string]' to type '[number, number]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Type 'string' is not comparable to type 'number'.
tests/cases/conformance/types/tuple/castingTuple.ts(31,10): error TS2352: Conversion of type '[C, D]' to type '[A, I]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
@@ -50,7 +50,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot
var eleFromCDA1 = classCDATuple[2]; // A
var eleFromCDA2 = classCDATuple[5]; // C | D | A
~
!!! error TS2733: Index '5' is out-of-bounds in tuple of length 3.
!!! error TS2339: Property '5' does not exist on type '[C, D, A]'.
var t10: [E1, E2] = [E1.one, E2.one];
var t11 = <[number, number]>t10;
var array1 = <{}[]>emptyObjTuple;
+2 -2
View File
@@ -83,8 +83,8 @@ var eleFromCDA1 = classCDATuple[2]; // A
>2 : 2
var eleFromCDA2 = classCDATuple[5]; // C | D | A
>eleFromCDA2 : A | C | D
>classCDATuple[5] : A | C | D
>eleFromCDA2 : undefined
>classCDATuple[5] : undefined
>classCDATuple : [C, D, A]
>5 : 5
@@ -5,7 +5,7 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(23,25):
tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(24,19): 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(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 | 1', but here has type 'string'.
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.
@@ -97,7 +97,7 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9):
var x: number;
var y: string;
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'y' must be of type 'string | 1', but here has type 'string'.
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'y' must be of type 'string | number', but here has type 'string'.
}
function f8() {
@@ -238,7 +238,7 @@ function f7() {
var [x = 0, y = 1] = [1, "hello"]; // Error, initializer for y must be string
>x : number
>0 : 0
>y : string | 1
>y : string | number
>1 : 1
>[1, "hello"] : [number, string]
>1 : 1
@@ -248,7 +248,7 @@ function f7() {
>x : number
var y: string;
>y : string | 1
>y : string | number
}
function f8() {
@@ -39,7 +39,7 @@ function bar(): J {
>3 : 3
}
var [b3 = "string", b4, b5] = bar(); // Error
>b3 : Number | "string"
>b3 : string | Number
>"string" : "string"
>b4 : Number
>b5 : Number
@@ -62,9 +62,9 @@ var [b2 = 3, b3 = true, b4 = temp] = [3, false, { t1: false, t2: "hello" }];
>"hello" : "hello"
var [b5 = 3, b6 = true, b7 = temp] = [undefined, undefined, undefined];
>b5 : 3
>b5 : number
>3 : 3
>b6 : true
>b6 : boolean
>true : true
>b7 : { t1: boolean; t2: string; }
>temp : { t1: boolean; t2: string; }
@@ -62,9 +62,9 @@ var [b2 = 3, b3 = true, b4 = temp] = [3, false, { t1: false, t2: "hello" }];
>"hello" : "hello"
var [b5 = 3, b6 = true, b7 = temp] = [undefined, undefined, undefined];
>b5 : 3
>b5 : number
>3 : 3
>b6 : true
>b6 : boolean
>true : true
>b7 : { t1: boolean; t2: string; }
>temp : { t1: boolean; t2: string; }
@@ -62,9 +62,9 @@ var [b2 = 3, b3 = true, b4 = temp] = [3, false, { t1: false, t2: "hello" }];
>"hello" : "hello"
var [b5 = 3, b6 = true, b7 = temp] = [undefined, undefined, undefined];
>b5 : 3
>b5 : number
>3 : 3
>b6 : true
>b6 : boolean
>true : true
>b7 : { t1: boolean; t2: string; }
>temp : { t1: boolean; t2: string; }
@@ -1,8 +1,8 @@
tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts(2,11): error TS2733: Index '0' is out-of-bounds in tuple of length 0.
tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts(2,11): error TS2339: Property '0' does not exist on type '[]'.
==== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts (1 errors) ====
let x = <[]>[];
let y = x[0];
~
!!! error TS2733: Index '0' is out-of-bounds in tuple of length 0.
!!! error TS2339: Property '0' does not exist on type '[]'.
@@ -9,4 +9,4 @@ var y = x[0];
//// [emptyTuplesTypeAssertion01.d.ts]
declare let x: [];
declare let y: never;
declare let y: undefined;
@@ -5,8 +5,8 @@ let x = <[]>[];
>[] : []
let y = x[0];
>y : never
>x[0] : never
>y : undefined
>x[0] : undefined
>x : []
>0 : 0
@@ -1,8 +1,8 @@
tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts(2,11): error TS2733: Index '0' is out-of-bounds in tuple of length 0.
tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts(2,11): error TS2339: Property '0' does not exist on type '[]'.
==== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts (1 errors) ====
let x = [] as [];
let y = x[0];
~
!!! error TS2733: Index '0' is out-of-bounds in tuple of length 0.
!!! error TS2339: Property '0' does not exist on type '[]'.
@@ -9,4 +9,4 @@ var y = x[0];
//// [emptyTuplesTypeAssertion02.d.ts]
declare let x: [];
declare let y: never;
declare let y: undefined;
@@ -5,8 +5,8 @@ let x = [] as [];
>[] : []
let y = x[0];
>y : never
>x[0] : never
>y : undefined
>x[0] : undefined
>x : []
>0 : 0
+1 -1
View File
@@ -13,7 +13,7 @@ for (var {x: a = "", y: b = true} of array) {
>a : string
>"" : ""
>y : any
>b : number | true
>b : number | boolean
>true : true
>array : { x: string; y: number; }[]
@@ -1,11 +1,10 @@
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(12,1): error TS2322: Type '[string, number, boolean, boolean]' is not assignable to type '[string, number]'.
Types of property 'length' are incompatible.
Type '4' is not assignable to type '2'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(13,20): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,1): error TS2322: Type '{ a: string; }' is not assignable to type 'string | number'.
Type '{ a: string; }' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,11): error TS2733: Index '3' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(15,20): error TS2733: Index '3' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(13,20): error TS2339: Property '2' does not exist on type '[string, number]'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,1): error TS2322: Type '{ a: string; }' is not assignable to type 'undefined'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,11): error TS2339: Property '3' does not exist on type '[string, number]'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(15,20): error TS2339: Property '3' does not exist on type '[string, number]'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,14): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,17): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(23,14): error TS2322: Type '{}' is not assignable to type 'string'.
@@ -33,16 +32,15 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTup
!!! error TS2322: Type '4' is not assignable to type '2'.
var e3 = i1.tuple1[2]; // {}
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[string, number]'.
i1.tuple1[3] = { a: "string" };
~~~~~~~~~~~~
!!! error TS2322: Type '{ a: string; }' is not assignable to type 'string | number'.
!!! error TS2322: Type '{ a: string; }' is not assignable to type 'number'.
!!! error TS2322: Type '{ a: string; }' is not assignable to type 'undefined'.
~
!!! error TS2733: Index '3' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '3' does not exist on type '[string, number]'.
var e4 = i1.tuple1[3]; // {}
~
!!! error TS2733: Index '3' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '3' does not exist on type '[string, number]'.
i2.tuple1 = ["foo", 5];
i2.tuple1 = ["foo", "bar"];
i2.tuple1 = [5, "bar"];
@@ -48,8 +48,8 @@ i1.tuple1 = ["foo", 5, false, true];
>true : true
var e3 = i1.tuple1[2]; // {}
>e3 : string | number
>i1.tuple1[2] : string | number
>e3 : undefined
>i1.tuple1[2] : undefined
>i1.tuple1 : [string, number]
>i1 : I<string, number>
>tuple1 : [string, number]
@@ -57,7 +57,7 @@ var e3 = i1.tuple1[2]; // {}
i1.tuple1[3] = { a: "string" };
>i1.tuple1[3] = { a: "string" } : { a: string; }
>i1.tuple1[3] : string | number
>i1.tuple1[3] : undefined
>i1.tuple1 : [string, number]
>i1 : I<string, number>
>tuple1 : [string, number]
@@ -67,8 +67,8 @@ i1.tuple1[3] = { a: "string" };
>"string" : "string"
var e4 = i1.tuple1[3]; // {}
>e4 : string | number
>i1.tuple1[3] : string | number
>e4 : undefined
>i1.tuple1[3] : undefined
>i1.tuple1 : [string, number]
>i1 : I<string, number>
>tuple1 : [string, number]
@@ -1,7 +1,7 @@
tests/cases/conformance/types/tuple/indexerWithTuple.ts(11,25): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/tuple/indexerWithTuple.ts(17,27): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/tuple/indexerWithTuple.ts(20,30): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/tuple/indexerWithTuple.ts(11,25): error TS2339: Property '2' does not exist on type '[string, number]'.
tests/cases/conformance/types/tuple/indexerWithTuple.ts(17,27): error TS2339: Property '2' does not exist on type '[number, [string, number]]'.
tests/cases/conformance/types/tuple/indexerWithTuple.ts(20,30): error TS2339: Property '2' does not exist on type '[number, string | number]'.
tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2339: Property '2' does not exist on type '[boolean, string | number]'.
==== tests/cases/conformance/types/tuple/indexerWithTuple.ts (4 errors) ====
@@ -17,7 +17,7 @@ tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2733: In
var ele11 = strNumTuple[1]; // number
var ele12 = strNumTuple[2]; // string | number
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[string, number]'.
var ele13 = strNumTuple[idx0]; // string | number
var ele14 = strNumTuple[idx1]; // string | number
var ele15 = strNumTuple["0"]; // string
@@ -25,12 +25,12 @@ tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2733: In
var strNumTuple1 = numTupleTuple[1]; //[string, number];
var ele17 = numTupleTuple[2]; // number | [string, number]
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[number, [string, number]]'.
var eleUnion10 = unionTuple1[0]; // number
var eleUnion11 = unionTuple1[1]; // string | number
var eleUnion12 = unionTuple1[2]; // string | number
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[number, string | number]'.
var eleUnion13 = unionTuple1[idx0]; // string | number
var eleUnion14 = unionTuple1[idx1]; // string | number
var eleUnion15 = unionTuple1["0"]; // number
@@ -40,7 +40,7 @@ tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2733: In
var eleUnion21 = unionTuple2[1]; // string | number
var eleUnion22 = unionTuple2[2]; // string | number | boolean
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[boolean, string | number]'.
var eleUnion23 = unionTuple2[idx0]; // string | number | boolean
var eleUnion24 = unionTuple2[idx1]; // string | number | boolean
var eleUnion25 = unionTuple2["0"]; // boolean
@@ -47,8 +47,8 @@ var ele11 = strNumTuple[1]; // number
>1 : 1
var ele12 = strNumTuple[2]; // string | number
>ele12 : string | number
>strNumTuple[2] : string | number
>ele12 : undefined
>strNumTuple[2] : undefined
>strNumTuple : [string, number]
>2 : 2
@@ -83,8 +83,8 @@ var strNumTuple1 = numTupleTuple[1]; //[string, number];
>1 : 1
var ele17 = numTupleTuple[2]; // number | [string, number]
>ele17 : number | [string, number]
>numTupleTuple[2] : number | [string, number]
>ele17 : undefined
>numTupleTuple[2] : undefined
>numTupleTuple : [number, [string, number]]
>2 : 2
@@ -101,8 +101,8 @@ var eleUnion11 = unionTuple1[1]; // string | number
>1 : 1
var eleUnion12 = unionTuple1[2]; // string | number
>eleUnion12 : string | number
>unionTuple1[2] : string | number
>eleUnion12 : undefined
>unionTuple1[2] : undefined
>unionTuple1 : [number, string | number]
>2 : 2
@@ -143,8 +143,8 @@ var eleUnion21 = unionTuple2[1]; // string | number
>1 : 1
var eleUnion22 = unionTuple2[2]; // string | number | boolean
>eleUnion22 : string | number | boolean
>unionTuple2[2] : string | number | boolean
>eleUnion22 : undefined
>unionTuple2[2] : undefined
>unionTuple2 : [boolean, string | number]
>2 : 2
@@ -61,12 +61,11 @@ type Q21 = Shape[WIDTH_OR_HEIGHT]; // number
type Q30 = [string, number][0]; // string
type Q31 = [string, number][1]; // number
type Q32 = [string, number][2]; // string | number
type Q32 = [string, number][number]; // string | number
type Q33 = [string, number][E.A]; // string
type Q34 = [string, number][E.B]; // number
type Q35 = [string, number][E.C]; // string | number
type Q36 = [string, number]["0"]; // string
type Q37 = [string, number]["1"]; // string
type Q35 = [string, number]["0"]; // string
type Q36 = [string, number]["1"]; // string
type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no"
type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no"
@@ -1147,12 +1146,11 @@ declare type Q20 = Shape[NAME];
declare type Q21 = Shape[WIDTH_OR_HEIGHT];
declare type Q30 = [string, number][0];
declare type Q31 = [string, number][1];
declare type Q32 = [string, number][2];
declare type Q32 = [string, number][number];
declare type Q33 = [string, number][E.A];
declare type Q34 = [string, number][E.B];
declare type Q35 = [string, number][E.C];
declare type Q36 = [string, number]["0"];
declare type Q37 = [string, number]["1"];
declare type Q35 = [string, number]["0"];
declare type Q36 = [string, number]["1"];
declare type Q40 = (Shape | Options)["visible"];
declare type Q41 = (Shape & Options)["visible"];
declare type Q50 = Dictionary<Shape>["howdy"];
File diff suppressed because it is too large Load Diff
@@ -145,7 +145,7 @@ type Q30 = [string, number][0]; // string
type Q31 = [string, number][1]; // number
>Q31 : number
type Q32 = [string, number][2]; // string | number
type Q32 = [string, number][number]; // string | number
>Q32 : string | number
type Q33 = [string, number][E.A]; // string
@@ -156,15 +156,11 @@ type Q34 = [string, number][E.B]; // number
>Q34 : number
>E : any
type Q35 = [string, number][E.C]; // string | number
>Q35 : string | number
>E : any
type Q35 = [string, number]["0"]; // string
>Q35 : string
type Q36 = [string, number]["0"]; // string
>Q36 : string
type Q37 = [string, number]["1"]; // string
>Q37 : number
type Q36 = [string, number]["1"]; // string
>Q36 : number
type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no"
>Q40 : boolean | "yes" | "no"
@@ -44,7 +44,7 @@ let { b = "foo" as "foo" } = { b: "bar" };
>"bar" : "bar"
let { c = "foo" } = { c: "bar" as "bar" };
>c : "foo" | "bar"
>c : string
>"foo" : "foo"
>{ c: "bar" as "bar" } : { c?: "bar"; }
>c : "bar"
@@ -1,5 +1,5 @@
tests/cases/conformance/types/tuple/tupleLengthCheck.ts(5,14): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/tuple/tupleLengthCheck.ts(6,14): error TS2733: Index '1000' is out-of-bounds in tuple of length 2.
tests/cases/conformance/types/tuple/tupleLengthCheck.ts(5,14): error TS2339: Property '2' does not exist on type '[number, string]'.
tests/cases/conformance/types/tuple/tupleLengthCheck.ts(6,14): error TS2339: Property '1000' does not exist on type '[number, string]'.
==== tests/cases/conformance/types/tuple/tupleLengthCheck.ts (2 errors) ====
@@ -9,10 +9,10 @@ tests/cases/conformance/types/tuple/tupleLengthCheck.ts(6,14): error TS2733: Ind
const a1 = a[1]
const a2 = a[2]
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[number, string]'.
const a3 = a[1000]
~~~~
!!! error TS2733: Index '1000' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '1000' does not exist on type '[number, string]'.
const a4 = rest[1]
const a5 = rest[2]
@@ -12,14 +12,14 @@ const a1 = a[1]
>1 : 1
const a2 = a[2]
>a2 : string | number
>a[2] : string | number
>a2 : undefined
>a[2] : undefined
>a : [number, string]
>2 : 2
const a3 = a[1000]
>a3 : string | number
>a[1000] : string | number
>a3 : undefined
>a[1000] : undefined
>a : [number, string]
>1000 : 1000
@@ -1,4 +1,5 @@
tests/cases/compiler/tupleTypes.ts(11,12): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/compiler/tupleTypes.ts(11,12): error TS2339: Property '2' does not exist on type '[number, string]'.
tests/cases/compiler/tupleTypes.ts(12,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type 'undefined', but here has type 'string | number'.
tests/cases/compiler/tupleTypes.ts(14,1): error TS2322: Type '[]' is not assignable to type '[number, string]'.
Property '0' is missing in type '[]'.
tests/cases/compiler/tupleTypes.ts(15,1): error TS2322: Type '[number]' is not assignable to type '[number, string]'.
@@ -8,7 +9,8 @@ tests/cases/compiler/tupleTypes.ts(17,15): error TS2322: Type 'number' is not as
tests/cases/compiler/tupleTypes.ts(18,1): error TS2322: Type '[number, string, number]' is not assignable to type '[number, string]'.
Types of property 'length' are incompatible.
Type '3' is not assignable to type '2'.
tests/cases/compiler/tupleTypes.ts(35,14): error TS2733: Index '2' is out-of-bounds in tuple of length 2.
tests/cases/compiler/tupleTypes.ts(35,14): error TS2339: Property '2' does not exist on type '[number, string]'.
tests/cases/compiler/tupleTypes.ts(36,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'tt2' must be of type 'undefined', but here has type 'string | number'.
tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type '[]' is not assignable to type '[number, string]'.
tests/cases/compiler/tupleTypes.ts(47,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'.
Type 'string | number' is not assignable to type 'number'.
@@ -22,7 +24,7 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n
Type '{}' is not assignable to type 'string'.
==== tests/cases/compiler/tupleTypes.ts (12 errors) ====
==== tests/cases/compiler/tupleTypes.ts (14 errors) ====
var v1: []; // Error
var v2: [number];
var v3: [number, string];
@@ -35,8 +37,10 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n
var t1: string;
var t2 = t[2]; // number|string
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[number, string]'.
var t2: number|string;
~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type 'undefined', but here has type 'string | number'.
t = []; // Error
~
@@ -75,8 +79,10 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n
var tt1: string;
var tt2 = tt[2];
~
!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2.
!!! error TS2339: Property '2' does not exist on type '[number, string]'.
var tt2: number | string;
~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'tt2' must be of type 'undefined', but here has type 'string | number'.
tt = tuple2(1, undefined);
tt = [1, undefined];
+6 -6
View File
@@ -33,13 +33,13 @@ var t1: string;
>t1 : string
var t2 = t[2]; // number|string
>t2 : string | number
>t[2] : string | number
>t2 : undefined
>t[2] : undefined
>t : [number, string]
>2 : 2
var t2: number|string;
>t2 : string | number
>t2 : undefined
t = []; // Error
>t = [] : []
@@ -144,13 +144,13 @@ var tt1: string;
>tt1 : string
var tt2 = tt[2];
>tt2 : string | number
>tt[2] : string | number
>tt2 : undefined
>tt[2] : undefined
>tt : [number, string]
>2 : 2
var tt2: number | string;
>tt2 : string | number
>tt2 : undefined
tt = tuple2(1, undefined);
>tt = tuple2(1, undefined) : [number, any]
@@ -0,0 +1,90 @@
tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(8,15): error TS2339: Property '2' does not exist on type '[string, number]'.
tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(13,15): error TS2339: Property '2' does not exist on type 'T2'.
tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(27,20): error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'.
tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(28,20): error TS2460: Type 'T2' has no property '2'.
tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(31,16): error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'.
tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(32,16): error TS2460: Type 'T2' has no property '2'.
tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(37,18): error TS2339: Property '2' does not exist on type '[string, number]'.
tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts(41,18): error TS2339: Property '2' does not exist on type 'T2'.
==== tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts (8 errors) ====
type T1 = [string, number];
type T2 = [boolean] | [string, number];
type T3 = [string, ...number[]];
type T4 = [boolean] | [string, ...number[]];
type T10 = T1[0]; // string
type T11 = T1[1]; // number
type T12 = T1[2]; // undefined
~
!!! error TS2339: Property '2' does not exist on type '[string, number]'.
type T1N = T1[number]; // string | number
type T20 = T2[0]; // string | boolean
type T21 = T2[1]; // number | undefined
type T22 = T2[2]; // undefined
~
!!! error TS2339: Property '2' does not exist on type 'T2'.
type T2N = T2[number]; // string | number | boolean
type T30 = T3[0]; // string
type T31 = T3[1]; // number
type T32 = T3[2]; // number
type T3N = T3[number]; // string | number
type T40 = T4[0]; // string | boolean
type T41 = T4[1]; // number | undefined
type T42 = T4[2]; // number | undefined
type T4N = T4[number]; // string | number | boolean
function f1(t1: T1, t2: T2, t3: T3, t4: T4, x: number) {
let [d10, d11, d12] = t1; // string, number
~~~
!!! error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'.
let [d20, d21, d22] = t2; // string | boolean, number | undefined
~~~
!!! error TS2460: Type 'T2' has no property '2'.
let [d30, d31, d32] = t3; // string, number, number
let [d40, d41, d42] = t4; // string | boolean, number | undefined, number | undefined
[d10, d11, d12] = t1;
~~~
!!! error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'.
[d20, d21, d22] = t2;
~~~
!!! error TS2460: Type 'T2' has no property '2'.
[d30, d31, d32] = t3;
[d40, d41, d42] = t4;
let t10 = t1[0]; // string
let t11 = t1[1]; // number
let t12 = t1[2]; // undefined
~
!!! error TS2339: Property '2' does not exist on type '[string, number]'.
let t1x = t1[x]; // string | number
let t20 = t2[0]; // string | boolean
let t21 = t2[1]; // number | undefined
let t22 = t2[2]; // undefined
~
!!! error TS2339: Property '2' does not exist on type 'T2'.
let t2x = t2[x]; // string | number | boolean
let t30 = t3[0]; // string
let t31 = t3[1]; // number
let t32 = t3[2]; // number
let t3x = t3[x]; // string | number
let t40 = t4[0]; // string | boolean
let t41 = t4[1]; // number | undefined
let t42 = t4[2]; // number | undefined
let t4x = t4[x]; // string | number | boolean
t1[1] = 42;
t2[1] = 42;
t3[1] = 42;
t4[1] = 42;
}
// Repro from #27543
type Unioned = [string] | [string, number];
const ex: Unioned = ["hi"] as Unioned;
const [x, y] = ex;
@@ -0,0 +1,99 @@
//// [unionsOfTupleTypes1.ts]
type T1 = [string, number];
type T2 = [boolean] | [string, number];
type T3 = [string, ...number[]];
type T4 = [boolean] | [string, ...number[]];
type T10 = T1[0]; // string
type T11 = T1[1]; // number
type T12 = T1[2]; // undefined
type T1N = T1[number]; // string | number
type T20 = T2[0]; // string | boolean
type T21 = T2[1]; // number | undefined
type T22 = T2[2]; // undefined
type T2N = T2[number]; // string | number | boolean
type T30 = T3[0]; // string
type T31 = T3[1]; // number
type T32 = T3[2]; // number
type T3N = T3[number]; // string | number
type T40 = T4[0]; // string | boolean
type T41 = T4[1]; // number | undefined
type T42 = T4[2]; // number | undefined
type T4N = T4[number]; // string | number | boolean
function f1(t1: T1, t2: T2, t3: T3, t4: T4, x: number) {
let [d10, d11, d12] = t1; // string, number
let [d20, d21, d22] = t2; // string | boolean, number | undefined
let [d30, d31, d32] = t3; // string, number, number
let [d40, d41, d42] = t4; // string | boolean, number | undefined, number | undefined
[d10, d11, d12] = t1;
[d20, d21, d22] = t2;
[d30, d31, d32] = t3;
[d40, d41, d42] = t4;
let t10 = t1[0]; // string
let t11 = t1[1]; // number
let t12 = t1[2]; // undefined
let t1x = t1[x]; // string | number
let t20 = t2[0]; // string | boolean
let t21 = t2[1]; // number | undefined
let t22 = t2[2]; // undefined
let t2x = t2[x]; // string | number | boolean
let t30 = t3[0]; // string
let t31 = t3[1]; // number
let t32 = t3[2]; // number
let t3x = t3[x]; // string | number
let t40 = t4[0]; // string | boolean
let t41 = t4[1]; // number | undefined
let t42 = t4[2]; // number | undefined
let t4x = t4[x]; // string | number | boolean
t1[1] = 42;
t2[1] = 42;
t3[1] = 42;
t4[1] = 42;
}
// Repro from #27543
type Unioned = [string] | [string, number];
const ex: Unioned = ["hi"] as Unioned;
const [x, y] = ex;
//// [unionsOfTupleTypes1.js]
"use strict";
function f1(t1, t2, t3, t4, x) {
var d10 = t1[0], d11 = t1[1], d12 = t1[2]; // string, number
var d20 = t2[0], d21 = t2[1], d22 = t2[2]; // string | boolean, number | undefined
var d30 = t3[0], d31 = t3[1], d32 = t3[2]; // string, number, number
var d40 = t4[0], d41 = t4[1], d42 = t4[2]; // string | boolean, number | undefined, number | undefined
d10 = t1[0], d11 = t1[1], d12 = t1[2];
d20 = t2[0], d21 = t2[1], d22 = t2[2];
d30 = t3[0], d31 = t3[1], d32 = t3[2];
d40 = t4[0], d41 = t4[1], d42 = t4[2];
var t10 = t1[0]; // string
var t11 = t1[1]; // number
var t12 = t1[2]; // undefined
var t1x = t1[x]; // string | number
var t20 = t2[0]; // string | boolean
var t21 = t2[1]; // number | undefined
var t22 = t2[2]; // undefined
var t2x = t2[x]; // string | number | boolean
var t30 = t3[0]; // string
var t31 = t3[1]; // number
var t32 = t3[2]; // number
var t3x = t3[x]; // string | number
var t40 = t4[0]; // string | boolean
var t41 = t4[1]; // number | undefined
var t42 = t4[2]; // number | undefined
var t4x = t4[x]; // string | number | boolean
t1[1] = 42;
t2[1] = 42;
t3[1] = 42;
t4[1] = 42;
}
var ex = ["hi"];
var x = ex[0], y = ex[1];
@@ -0,0 +1,241 @@
=== tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts ===
type T1 = [string, number];
>T1 : Symbol(T1, Decl(unionsOfTupleTypes1.ts, 0, 0))
type T2 = [boolean] | [string, number];
>T2 : Symbol(T2, Decl(unionsOfTupleTypes1.ts, 0, 27))
type T3 = [string, ...number[]];
>T3 : Symbol(T3, Decl(unionsOfTupleTypes1.ts, 1, 39))
type T4 = [boolean] | [string, ...number[]];
>T4 : Symbol(T4, Decl(unionsOfTupleTypes1.ts, 2, 32))
type T10 = T1[0]; // string
>T10 : Symbol(T10, Decl(unionsOfTupleTypes1.ts, 3, 44))
>T1 : Symbol(T1, Decl(unionsOfTupleTypes1.ts, 0, 0))
type T11 = T1[1]; // number
>T11 : Symbol(T11, Decl(unionsOfTupleTypes1.ts, 5, 17))
>T1 : Symbol(T1, Decl(unionsOfTupleTypes1.ts, 0, 0))
type T12 = T1[2]; // undefined
>T12 : Symbol(T12, Decl(unionsOfTupleTypes1.ts, 6, 17))
>T1 : Symbol(T1, Decl(unionsOfTupleTypes1.ts, 0, 0))
type T1N = T1[number]; // string | number
>T1N : Symbol(T1N, Decl(unionsOfTupleTypes1.ts, 7, 17))
>T1 : Symbol(T1, Decl(unionsOfTupleTypes1.ts, 0, 0))
type T20 = T2[0]; // string | boolean
>T20 : Symbol(T20, Decl(unionsOfTupleTypes1.ts, 8, 22))
>T2 : Symbol(T2, Decl(unionsOfTupleTypes1.ts, 0, 27))
type T21 = T2[1]; // number | undefined
>T21 : Symbol(T21, Decl(unionsOfTupleTypes1.ts, 10, 17))
>T2 : Symbol(T2, Decl(unionsOfTupleTypes1.ts, 0, 27))
type T22 = T2[2]; // undefined
>T22 : Symbol(T22, Decl(unionsOfTupleTypes1.ts, 11, 17))
>T2 : Symbol(T2, Decl(unionsOfTupleTypes1.ts, 0, 27))
type T2N = T2[number]; // string | number | boolean
>T2N : Symbol(T2N, Decl(unionsOfTupleTypes1.ts, 12, 17))
>T2 : Symbol(T2, Decl(unionsOfTupleTypes1.ts, 0, 27))
type T30 = T3[0]; // string
>T30 : Symbol(T30, Decl(unionsOfTupleTypes1.ts, 13, 22))
>T3 : Symbol(T3, Decl(unionsOfTupleTypes1.ts, 1, 39))
type T31 = T3[1]; // number
>T31 : Symbol(T31, Decl(unionsOfTupleTypes1.ts, 15, 17))
>T3 : Symbol(T3, Decl(unionsOfTupleTypes1.ts, 1, 39))
type T32 = T3[2]; // number
>T32 : Symbol(T32, Decl(unionsOfTupleTypes1.ts, 16, 17))
>T3 : Symbol(T3, Decl(unionsOfTupleTypes1.ts, 1, 39))
type T3N = T3[number]; // string | number
>T3N : Symbol(T3N, Decl(unionsOfTupleTypes1.ts, 17, 17))
>T3 : Symbol(T3, Decl(unionsOfTupleTypes1.ts, 1, 39))
type T40 = T4[0]; // string | boolean
>T40 : Symbol(T40, Decl(unionsOfTupleTypes1.ts, 18, 22))
>T4 : Symbol(T4, Decl(unionsOfTupleTypes1.ts, 2, 32))
type T41 = T4[1]; // number | undefined
>T41 : Symbol(T41, Decl(unionsOfTupleTypes1.ts, 20, 17))
>T4 : Symbol(T4, Decl(unionsOfTupleTypes1.ts, 2, 32))
type T42 = T4[2]; // number | undefined
>T42 : Symbol(T42, Decl(unionsOfTupleTypes1.ts, 21, 17))
>T4 : Symbol(T4, Decl(unionsOfTupleTypes1.ts, 2, 32))
type T4N = T4[number]; // string | number | boolean
>T4N : Symbol(T4N, Decl(unionsOfTupleTypes1.ts, 22, 17))
>T4 : Symbol(T4, Decl(unionsOfTupleTypes1.ts, 2, 32))
function f1(t1: T1, t2: T2, t3: T3, t4: T4, x: number) {
>f1 : Symbol(f1, Decl(unionsOfTupleTypes1.ts, 23, 22))
>t1 : Symbol(t1, Decl(unionsOfTupleTypes1.ts, 25, 12))
>T1 : Symbol(T1, Decl(unionsOfTupleTypes1.ts, 0, 0))
>t2 : Symbol(t2, Decl(unionsOfTupleTypes1.ts, 25, 19))
>T2 : Symbol(T2, Decl(unionsOfTupleTypes1.ts, 0, 27))
>t3 : Symbol(t3, Decl(unionsOfTupleTypes1.ts, 25, 27))
>T3 : Symbol(T3, Decl(unionsOfTupleTypes1.ts, 1, 39))
>t4 : Symbol(t4, Decl(unionsOfTupleTypes1.ts, 25, 35))
>T4 : Symbol(T4, Decl(unionsOfTupleTypes1.ts, 2, 32))
>x : Symbol(x, Decl(unionsOfTupleTypes1.ts, 25, 43))
let [d10, d11, d12] = t1; // string, number
>d10 : Symbol(d10, Decl(unionsOfTupleTypes1.ts, 26, 9))
>d11 : Symbol(d11, Decl(unionsOfTupleTypes1.ts, 26, 13))
>d12 : Symbol(d12, Decl(unionsOfTupleTypes1.ts, 26, 18))
>t1 : Symbol(t1, Decl(unionsOfTupleTypes1.ts, 25, 12))
let [d20, d21, d22] = t2; // string | boolean, number | undefined
>d20 : Symbol(d20, Decl(unionsOfTupleTypes1.ts, 27, 9))
>d21 : Symbol(d21, Decl(unionsOfTupleTypes1.ts, 27, 13))
>d22 : Symbol(d22, Decl(unionsOfTupleTypes1.ts, 27, 18))
>t2 : Symbol(t2, Decl(unionsOfTupleTypes1.ts, 25, 19))
let [d30, d31, d32] = t3; // string, number, number
>d30 : Symbol(d30, Decl(unionsOfTupleTypes1.ts, 28, 9))
>d31 : Symbol(d31, Decl(unionsOfTupleTypes1.ts, 28, 13))
>d32 : Symbol(d32, Decl(unionsOfTupleTypes1.ts, 28, 18))
>t3 : Symbol(t3, Decl(unionsOfTupleTypes1.ts, 25, 27))
let [d40, d41, d42] = t4; // string | boolean, number | undefined, number | undefined
>d40 : Symbol(d40, Decl(unionsOfTupleTypes1.ts, 29, 9))
>d41 : Symbol(d41, Decl(unionsOfTupleTypes1.ts, 29, 13))
>d42 : Symbol(d42, Decl(unionsOfTupleTypes1.ts, 29, 18))
>t4 : Symbol(t4, Decl(unionsOfTupleTypes1.ts, 25, 35))
[d10, d11, d12] = t1;
>d10 : Symbol(d10, Decl(unionsOfTupleTypes1.ts, 26, 9))
>d11 : Symbol(d11, Decl(unionsOfTupleTypes1.ts, 26, 13))
>d12 : Symbol(d12, Decl(unionsOfTupleTypes1.ts, 26, 18))
>t1 : Symbol(t1, Decl(unionsOfTupleTypes1.ts, 25, 12))
[d20, d21, d22] = t2;
>d20 : Symbol(d20, Decl(unionsOfTupleTypes1.ts, 27, 9))
>d21 : Symbol(d21, Decl(unionsOfTupleTypes1.ts, 27, 13))
>d22 : Symbol(d22, Decl(unionsOfTupleTypes1.ts, 27, 18))
>t2 : Symbol(t2, Decl(unionsOfTupleTypes1.ts, 25, 19))
[d30, d31, d32] = t3;
>d30 : Symbol(d30, Decl(unionsOfTupleTypes1.ts, 28, 9))
>d31 : Symbol(d31, Decl(unionsOfTupleTypes1.ts, 28, 13))
>d32 : Symbol(d32, Decl(unionsOfTupleTypes1.ts, 28, 18))
>t3 : Symbol(t3, Decl(unionsOfTupleTypes1.ts, 25, 27))
[d40, d41, d42] = t4;
>d40 : Symbol(d40, Decl(unionsOfTupleTypes1.ts, 29, 9))
>d41 : Symbol(d41, Decl(unionsOfTupleTypes1.ts, 29, 13))
>d42 : Symbol(d42, Decl(unionsOfTupleTypes1.ts, 29, 18))
>t4 : Symbol(t4, Decl(unionsOfTupleTypes1.ts, 25, 35))
let t10 = t1[0]; // string
>t10 : Symbol(t10, Decl(unionsOfTupleTypes1.ts, 34, 7))
>t1 : Symbol(t1, Decl(unionsOfTupleTypes1.ts, 25, 12))
>0 : Symbol(0)
let t11 = t1[1]; // number
>t11 : Symbol(t11, Decl(unionsOfTupleTypes1.ts, 35, 7))
>t1 : Symbol(t1, Decl(unionsOfTupleTypes1.ts, 25, 12))
>1 : Symbol(1)
let t12 = t1[2]; // undefined
>t12 : Symbol(t12, Decl(unionsOfTupleTypes1.ts, 36, 7))
>t1 : Symbol(t1, Decl(unionsOfTupleTypes1.ts, 25, 12))
let t1x = t1[x]; // string | number
>t1x : Symbol(t1x, Decl(unionsOfTupleTypes1.ts, 37, 7))
>t1 : Symbol(t1, Decl(unionsOfTupleTypes1.ts, 25, 12))
>x : Symbol(x, Decl(unionsOfTupleTypes1.ts, 25, 43))
let t20 = t2[0]; // string | boolean
>t20 : Symbol(t20, Decl(unionsOfTupleTypes1.ts, 38, 7))
>t2 : Symbol(t2, Decl(unionsOfTupleTypes1.ts, 25, 19))
>0 : Symbol(0)
let t21 = t2[1]; // number | undefined
>t21 : Symbol(t21, Decl(unionsOfTupleTypes1.ts, 39, 7))
>t2 : Symbol(t2, Decl(unionsOfTupleTypes1.ts, 25, 19))
>1 : Symbol(1)
let t22 = t2[2]; // undefined
>t22 : Symbol(t22, Decl(unionsOfTupleTypes1.ts, 40, 7))
>t2 : Symbol(t2, Decl(unionsOfTupleTypes1.ts, 25, 19))
let t2x = t2[x]; // string | number | boolean
>t2x : Symbol(t2x, Decl(unionsOfTupleTypes1.ts, 41, 7))
>t2 : Symbol(t2, Decl(unionsOfTupleTypes1.ts, 25, 19))
>x : Symbol(x, Decl(unionsOfTupleTypes1.ts, 25, 43))
let t30 = t3[0]; // string
>t30 : Symbol(t30, Decl(unionsOfTupleTypes1.ts, 42, 7))
>t3 : Symbol(t3, Decl(unionsOfTupleTypes1.ts, 25, 27))
>0 : Symbol(0)
let t31 = t3[1]; // number
>t31 : Symbol(t31, Decl(unionsOfTupleTypes1.ts, 43, 7))
>t3 : Symbol(t3, Decl(unionsOfTupleTypes1.ts, 25, 27))
let t32 = t3[2]; // number
>t32 : Symbol(t32, Decl(unionsOfTupleTypes1.ts, 44, 7))
>t3 : Symbol(t3, Decl(unionsOfTupleTypes1.ts, 25, 27))
let t3x = t3[x]; // string | number
>t3x : Symbol(t3x, Decl(unionsOfTupleTypes1.ts, 45, 7))
>t3 : Symbol(t3, Decl(unionsOfTupleTypes1.ts, 25, 27))
>x : Symbol(x, Decl(unionsOfTupleTypes1.ts, 25, 43))
let t40 = t4[0]; // string | boolean
>t40 : Symbol(t40, Decl(unionsOfTupleTypes1.ts, 46, 7))
>t4 : Symbol(t4, Decl(unionsOfTupleTypes1.ts, 25, 35))
>0 : Symbol(0)
let t41 = t4[1]; // number | undefined
>t41 : Symbol(t41, Decl(unionsOfTupleTypes1.ts, 47, 7))
>t4 : Symbol(t4, Decl(unionsOfTupleTypes1.ts, 25, 35))
let t42 = t4[2]; // number | undefined
>t42 : Symbol(t42, Decl(unionsOfTupleTypes1.ts, 48, 7))
>t4 : Symbol(t4, Decl(unionsOfTupleTypes1.ts, 25, 35))
let t4x = t4[x]; // string | number | boolean
>t4x : Symbol(t4x, Decl(unionsOfTupleTypes1.ts, 49, 7))
>t4 : Symbol(t4, Decl(unionsOfTupleTypes1.ts, 25, 35))
>x : Symbol(x, Decl(unionsOfTupleTypes1.ts, 25, 43))
t1[1] = 42;
>t1 : Symbol(t1, Decl(unionsOfTupleTypes1.ts, 25, 12))
>1 : Symbol(1)
t2[1] = 42;
>t2 : Symbol(t2, Decl(unionsOfTupleTypes1.ts, 25, 19))
>1 : Symbol(1)
t3[1] = 42;
>t3 : Symbol(t3, Decl(unionsOfTupleTypes1.ts, 25, 27))
t4[1] = 42;
>t4 : Symbol(t4, Decl(unionsOfTupleTypes1.ts, 25, 35))
}
// Repro from #27543
type Unioned = [string] | [string, number];
>Unioned : Symbol(Unioned, Decl(unionsOfTupleTypes1.ts, 54, 1))
const ex: Unioned = ["hi"] as Unioned;
>ex : Symbol(ex, Decl(unionsOfTupleTypes1.ts, 59, 5))
>Unioned : Symbol(Unioned, Decl(unionsOfTupleTypes1.ts, 54, 1))
>Unioned : Symbol(Unioned, Decl(unionsOfTupleTypes1.ts, 54, 1))
const [x, y] = ex;
>x : Symbol(x, Decl(unionsOfTupleTypes1.ts, 61, 7))
>y : Symbol(y, Decl(unionsOfTupleTypes1.ts, 61, 9))
>ex : Symbol(ex, Decl(unionsOfTupleTypes1.ts, 59, 5))
@@ -0,0 +1,266 @@
=== tests/cases/conformance/types/tuple/unionsOfTupleTypes1.ts ===
type T1 = [string, number];
>T1 : [string, number]
type T2 = [boolean] | [string, number];
>T2 : T2
type T3 = [string, ...number[]];
>T3 : [string, ...number[]]
type T4 = [boolean] | [string, ...number[]];
>T4 : T4
type T10 = T1[0]; // string
>T10 : string
type T11 = T1[1]; // number
>T11 : number
type T12 = T1[2]; // undefined
>T12 : undefined
type T1N = T1[number]; // string | number
>T1N : string | number
type T20 = T2[0]; // string | boolean
>T20 : string | boolean
type T21 = T2[1]; // number | undefined
>T21 : number | undefined
type T22 = T2[2]; // undefined
>T22 : undefined
type T2N = T2[number]; // string | number | boolean
>T2N : string | number | boolean
type T30 = T3[0]; // string
>T30 : string
type T31 = T3[1]; // number
>T31 : number
type T32 = T3[2]; // number
>T32 : number
type T3N = T3[number]; // string | number
>T3N : string | number
type T40 = T4[0]; // string | boolean
>T40 : string | boolean
type T41 = T4[1]; // number | undefined
>T41 : number | undefined
type T42 = T4[2]; // number | undefined
>T42 : number | undefined
type T4N = T4[number]; // string | number | boolean
>T4N : string | number | boolean
function f1(t1: T1, t2: T2, t3: T3, t4: T4, x: number) {
>f1 : (t1: [string, number], t2: T2, t3: [string, ...number[]], t4: T4, x: number) => void
>t1 : [string, number]
>t2 : T2
>t3 : [string, ...number[]]
>t4 : T4
>x : number
let [d10, d11, d12] = t1; // string, number
>d10 : string
>d11 : number
>d12 : any
>t1 : [string, number]
let [d20, d21, d22] = t2; // string | boolean, number | undefined
>d20 : string | boolean
>d21 : number | undefined
>d22 : any
>t2 : T2
let [d30, d31, d32] = t3; // string, number, number
>d30 : string
>d31 : number
>d32 : number
>t3 : [string, ...number[]]
let [d40, d41, d42] = t4; // string | boolean, number | undefined, number | undefined
>d40 : string | boolean
>d41 : number | undefined
>d42 : number | undefined
>t4 : T4
[d10, d11, d12] = t1;
>[d10, d11, d12] = t1 : [string, number]
>[d10, d11, d12] : [string, number, any]
>d10 : string
>d11 : number
>d12 : any
>t1 : [string, number]
[d20, d21, d22] = t2;
>[d20, d21, d22] = t2 : T2
>[d20, d21, d22] : [string | boolean, number | undefined, any]
>d20 : string | boolean
>d21 : number | undefined
>d22 : any
>t2 : T2
[d30, d31, d32] = t3;
>[d30, d31, d32] = t3 : [string, ...number[]]
>[d30, d31, d32] : [string, number, number]
>d30 : string
>d31 : number
>d32 : number
>t3 : [string, ...number[]]
[d40, d41, d42] = t4;
>[d40, d41, d42] = t4 : T4
>[d40, d41, d42] : [string | boolean, number | undefined, number | undefined]
>d40 : string | boolean
>d41 : number | undefined
>d42 : number | undefined
>t4 : T4
let t10 = t1[0]; // string
>t10 : string
>t1[0] : string
>t1 : [string, number]
>0 : 0
let t11 = t1[1]; // number
>t11 : number
>t1[1] : number
>t1 : [string, number]
>1 : 1
let t12 = t1[2]; // undefined
>t12 : undefined
>t1[2] : undefined
>t1 : [string, number]
>2 : 2
let t1x = t1[x]; // string | number
>t1x : string | number
>t1[x] : string | number
>t1 : [string, number]
>x : number
let t20 = t2[0]; // string | boolean
>t20 : string | boolean
>t2[0] : string | boolean
>t2 : T2
>0 : 0
let t21 = t2[1]; // number | undefined
>t21 : number | undefined
>t2[1] : number | undefined
>t2 : T2
>1 : 1
let t22 = t2[2]; // undefined
>t22 : undefined
>t2[2] : undefined
>t2 : T2
>2 : 2
let t2x = t2[x]; // string | number | boolean
>t2x : string | number | boolean
>t2[x] : string | number | boolean
>t2 : T2
>x : number
let t30 = t3[0]; // string
>t30 : string
>t3[0] : string
>t3 : [string, ...number[]]
>0 : 0
let t31 = t3[1]; // number
>t31 : number
>t3[1] : number
>t3 : [string, ...number[]]
>1 : 1
let t32 = t3[2]; // number
>t32 : number
>t3[2] : number
>t3 : [string, ...number[]]
>2 : 2
let t3x = t3[x]; // string | number
>t3x : string | number
>t3[x] : string | number
>t3 : [string, ...number[]]
>x : number
let t40 = t4[0]; // string | boolean
>t40 : string | boolean
>t4[0] : string | boolean
>t4 : T4
>0 : 0
let t41 = t4[1]; // number | undefined
>t41 : number | undefined
>t4[1] : number | undefined
>t4 : T4
>1 : 1
let t42 = t4[2]; // number | undefined
>t42 : number | undefined
>t4[2] : number | undefined
>t4 : T4
>2 : 2
let t4x = t4[x]; // string | number | boolean
>t4x : string | number | boolean
>t4[x] : string | number | boolean
>t4 : T4
>x : number
t1[1] = 42;
>t1[1] = 42 : 42
>t1[1] : number
>t1 : [string, number]
>1 : 1
>42 : 42
t2[1] = 42;
>t2[1] = 42 : 42
>t2[1] : number | undefined
>t2 : T2
>1 : 1
>42 : 42
t3[1] = 42;
>t3[1] = 42 : 42
>t3[1] : number
>t3 : [string, ...number[]]
>1 : 1
>42 : 42
t4[1] = 42;
>t4[1] = 42 : 42
>t4[1] : number | undefined
>t4 : T4
>1 : 1
>42 : 42
}
// Repro from #27543
type Unioned = [string] | [string, number];
>Unioned : Unioned
const ex: Unioned = ["hi"] as Unioned;
>ex : Unioned
>["hi"] as Unioned : Unioned
>["hi"] : [string]
>"hi" : "hi"
const [x, y] = ex;
>x : string
>y : number | undefined
>ex : Unioned
@@ -63,12 +63,11 @@ type Q21 = Shape[WIDTH_OR_HEIGHT]; // number
type Q30 = [string, number][0]; // string
type Q31 = [string, number][1]; // number
type Q32 = [string, number][2]; // string | number
type Q32 = [string, number][number]; // string | number
type Q33 = [string, number][E.A]; // string
type Q34 = [string, number][E.B]; // number
type Q35 = [string, number][E.C]; // string | number
type Q36 = [string, number]["0"]; // string
type Q37 = [string, number]["1"]; // string
type Q35 = [string, number]["0"]; // string
type Q36 = [string, number]["1"]; // string
type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no"
type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no"
@@ -0,0 +1,64 @@
// @strict: true
type T1 = [string, number];
type T2 = [boolean] | [string, number];
type T3 = [string, ...number[]];
type T4 = [boolean] | [string, ...number[]];
type T10 = T1[0]; // string
type T11 = T1[1]; // number
type T12 = T1[2]; // undefined
type T1N = T1[number]; // string | number
type T20 = T2[0]; // string | boolean
type T21 = T2[1]; // number | undefined
type T22 = T2[2]; // undefined
type T2N = T2[number]; // string | number | boolean
type T30 = T3[0]; // string
type T31 = T3[1]; // number
type T32 = T3[2]; // number
type T3N = T3[number]; // string | number
type T40 = T4[0]; // string | boolean
type T41 = T4[1]; // number | undefined
type T42 = T4[2]; // number | undefined
type T4N = T4[number]; // string | number | boolean
function f1(t1: T1, t2: T2, t3: T3, t4: T4, x: number) {
let [d10, d11, d12] = t1; // string, number
let [d20, d21, d22] = t2; // string | boolean, number | undefined
let [d30, d31, d32] = t3; // string, number, number
let [d40, d41, d42] = t4; // string | boolean, number | undefined, number | undefined
[d10, d11, d12] = t1;
[d20, d21, d22] = t2;
[d30, d31, d32] = t3;
[d40, d41, d42] = t4;
let t10 = t1[0]; // string
let t11 = t1[1]; // number
let t12 = t1[2]; // undefined
let t1x = t1[x]; // string | number
let t20 = t2[0]; // string | boolean
let t21 = t2[1]; // number | undefined
let t22 = t2[2]; // undefined
let t2x = t2[x]; // string | number | boolean
let t30 = t3[0]; // string
let t31 = t3[1]; // number
let t32 = t3[2]; // number
let t3x = t3[x]; // string | number
let t40 = t4[0]; // string | boolean
let t41 = t4[1]; // number | undefined
let t42 = t4[2]; // number | undefined
let t4x = t4[x]; // string | number | boolean
t1[1] = 42;
t2[1] = 42;
t3[1] = 42;
t4[1] = 42;
}
// Repro from #27543
type Unioned = [string] | [string, number];
const ex: Unioned = ["hi"] as Unioned;
const [x, y] = ex;