Skip to content

Commit 1476eb4

Browse files
lefb766
authored and
committed
Add empty tuple type
1 parent d4c11bf commit 1476eb4

20 files changed

+201
-69
lines changed

src/compiler/checker.ts

+6-18
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ namespace ts {
332332

333333
const emptyStringType = getLiteralType("");
334334
const zeroType = getLiteralType(0);
335+
const emptyTupleType = createTupleType([]);
335336

336337
const resolutionTargets: TypeSystemEntity[] = [];
337338
const resolutionResults: boolean[] = [];
@@ -2621,16 +2622,8 @@ namespace ts {
26212622
return createArrayTypeNode(elementType);
26222623
}
26232624
else if (type.target.objectFlags & ObjectFlags.Tuple) {
2624-
if (typeArguments.length > 0) {
2625-
const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, getTypeReferenceArity(type)), context);
2626-
if (tupleConstituentNodes && tupleConstituentNodes.length > 0) {
2627-
return createTupleTypeNode(tupleConstituentNodes);
2628-
}
2629-
}
2630-
if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowEmptyTuple)) {
2631-
context.encounteredError = true;
2632-
}
2633-
return undefined;
2625+
const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, getTypeReferenceArity(type)), context) || [];
2626+
return createTupleTypeNode(tupleConstituentNodes);
26342627
}
26352628
else {
26362629
const outerTypeParameters = type.target.outerTypeParameters;
@@ -9898,7 +9891,7 @@ namespace ts {
98989891
}
98999892

99009893
function isTupleLikeType(type: Type): boolean {
9901-
return !!getPropertyOfType(type, "0" as __String);
9894+
return !!getPropertyOfType(type, "0" as __String) || type === emptyTupleType;
99029895
}
99039896

99049897
function isUnitType(type: Type): boolean {
@@ -13204,9 +13197,7 @@ namespace ts {
1320413197
}
1320513198
}
1320613199
}
13207-
if (elementTypes.length) {
13208-
return createTupleType(elementTypes);
13209-
}
13200+
return createTupleType(elementTypes);
1321013201
}
1321113202
}
1321213203
return createArrayType(elementTypes.length ?
@@ -18493,10 +18484,7 @@ namespace ts {
1849318484

1849418485
function checkTupleType(node: TupleTypeNode) {
1849518486
// Grammar checking
18496-
const hasErrorFromDisallowedTrailingComma = checkGrammarForDisallowedTrailingComma(node.elementTypes);
18497-
if (!hasErrorFromDisallowedTrailingComma && node.elementTypes.length === 0) {
18498-
grammarErrorOnNode(node, Diagnostics.A_tuple_type_element_list_cannot_be_empty);
18499-
}
18487+
checkGrammarForDisallowedTrailingComma(node.elementTypes);
1850018488

1850118489
forEach(node.elementTypes, checkSourceElement);
1850218490
}

src/compiler/diagnosticMessages.json

-4
Original file line numberDiff line numberDiff line change
@@ -355,10 +355,6 @@
355355
"category": "Error",
356356
"code": 1121
357357
},
358-
"A tuple type element list cannot be empty.": {
359-
"category": "Error",
360-
"code": 1122
361-
},
362358
"Variable declaration list cannot be empty.": {
363359
"category": "Error",
364360
"code": 1123

src/compiler/types.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -2692,9 +2692,8 @@ namespace ts {
26922692
AllowQualifedNameInPlaceOfIdentifier = 1 << 11,
26932693
AllowAnonymousIdentifier = 1 << 13,
26942694
AllowEmptyUnionOrIntersection = 1 << 14,
2695-
AllowEmptyTuple = 1 << 15,
26962695

2697-
IgnoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple,
2696+
IgnoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection,
26982697

26992698
// State
27002699
InObjectTypeLiteral = 1 << 20,

tests/baselines/reference/TupleType3.errors.txt

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== tests/cases/conformance/parser/ecmascript5/TupleTypes/TupleType3.ts ===
2+
var v: []
3+
>v : Symbol(v, Decl(TupleType3.ts, 0, 3))
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== tests/cases/conformance/parser/ecmascript5/TupleTypes/TupleType3.ts ===
2+
var v: []
3+
>v : []
4+

tests/baselines/reference/arrayLiterals3.errors.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(10,5): error TS2322: Type 'undefined[]' is not assignable to type '[any, any, any]'.
2-
Property '0' is missing in type 'undefined[]'.
1+
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(10,5): error TS2322: Type '[]' is not assignable to type '[any, any, any]'.
2+
Property '0' is missing in type '[]'.
33
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(11,5): error TS2322: Type '["string", number, boolean]' is not assignable to type '[boolean, string, number]'.
44
Type '"string"' is not assignable to type 'boolean'.
55
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(17,5): error TS2322: Type '[number, number, string, boolean]' is not assignable to type '[number, number]'.
@@ -32,8 +32,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error
3232

3333
var a0: [any, any, any] = []; // Error
3434
~~
35-
!!! error TS2322: Type 'undefined[]' is not assignable to type '[any, any, any]'.
36-
!!! error TS2322: Property '0' is missing in type 'undefined[]'.
35+
!!! error TS2322: Type '[]' is not assignable to type '[any, any, any]'.
36+
!!! error TS2322: Property '0' is missing in type '[]'.
3737
var a1: [boolean, string, number] = ["string", 1, true]; // Error
3838
~~
3939
!!! error TS2322: Type '["string", number, boolean]' is not assignable to type '[boolean, string, number]'.

tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt

-8
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
=== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts ===
2+
let x = <[]>[];
3+
>x : Symbol(x, Decl(emptyTuplesTypeAssertion01.ts, 0, 3))
4+
5+
let y = x[0];
6+
>y : Symbol(y, Decl(emptyTuplesTypeAssertion01.ts, 1, 3))
7+
>x : Symbol(x, Decl(emptyTuplesTypeAssertion01.ts, 0, 3))
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts ===
2+
let x = <[]>[];
3+
>x : []
4+
><[]>[] : []
5+
>[] : []
6+
7+
let y = x[0];
8+
>y : never
9+
>x[0] : never
10+
>x : []
11+
>0 : 0
12+

tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt

-8
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
=== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts ===
2+
let x = [] as [];
3+
>x : Symbol(x, Decl(emptyTuplesTypeAssertion02.ts, 0, 3))
4+
5+
let y = x[0];
6+
>y : Symbol(y, Decl(emptyTuplesTypeAssertion02.ts, 1, 3))
7+
>x : Symbol(x, Decl(emptyTuplesTypeAssertion02.ts, 0, 3))
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts ===
2+
let x = [] as [];
3+
>x : []
4+
>[] as [] : []
5+
>[] : []
6+
7+
let y = x[0];
8+
>y : never
9+
>x[0] : never
10+
>x : []
11+
>0 : 0
12+

tests/baselines/reference/tupleTypes.errors.txt

+52-15
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,40 @@
1-
tests/cases/compiler/tupleTypes.ts(1,9): error TS1122: A tuple type element list cannot be empty.
2-
tests/cases/compiler/tupleTypes.ts(14,1): error TS2322: Type 'undefined[]' is not assignable to type '[number, string]'.
3-
Property '0' is missing in type 'undefined[]'.
1+
tests/cases/compiler/tupleTypes.ts(14,1): error TS2322: Type '[]' is not assignable to type '[number, string]'.
2+
Property '0' is missing in type '[]'.
43
tests/cases/compiler/tupleTypes.ts(15,1): error TS2322: Type '[number]' is not assignable to type '[number, string]'.
54
Property '1' is missing in type '[number]'.
65
tests/cases/compiler/tupleTypes.ts(17,1): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
76
Type 'string' is not assignable to type 'number'.
8-
tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type 'undefined[]' is not assignable to type '[number, string]'.
9-
tests/cases/compiler/tupleTypes.ts(47,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'.
7+
tests/cases/compiler/tupleTypes.ts(25,1): error TS2322: Type '[number]' is not assignable to type '[]'.
8+
Types of property 'pop' are incompatible.
9+
Type '() => number' is not assignable to type '() => never'.
10+
Type 'number' is not assignable to type 'never'.
11+
tests/cases/compiler/tupleTypes.ts(48,1): error TS2322: Type '[]' is not assignable to type '[number, string]'.
12+
tests/cases/compiler/tupleTypes.ts(55,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'.
1013
Types of property 'pop' are incompatible.
1114
Type '() => string | number' is not assignable to type '() => number'.
1215
Type 'string | number' is not assignable to type 'number'.
1316
Type 'string' is not assignable to type 'number'.
14-
tests/cases/compiler/tupleTypes.ts(49,1): error TS2322: Type '[number, {}]' is not assignable to type 'number[]'.
17+
tests/cases/compiler/tupleTypes.ts(57,1): error TS2322: Type '[number, {}]' is not assignable to type 'number[]'.
1518
Types of property 'pop' are incompatible.
1619
Type '() => number | {}' is not assignable to type '() => number'.
1720
Type 'number | {}' is not assignable to type 'number'.
1821
Type '{}' is not assignable to type 'number'.
19-
tests/cases/compiler/tupleTypes.ts(50,1): error TS2322: Type '[number, number]' is not assignable to type '[number, string]'.
22+
tests/cases/compiler/tupleTypes.ts(59,1): error TS2322: Type '[number, number]' is not assignable to type '[number, string]'.
2023
Type 'number' is not assignable to type 'string'.
21-
tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'.
24+
tests/cases/compiler/tupleTypes.ts(60,1): error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'.
2225
Type '{}' is not assignable to type 'string'.
26+
tests/cases/compiler/tupleTypes.ts(61,1): error TS2322: Type '[]' is not assignable to type '[number, string]'.
27+
tests/cases/compiler/tupleTypes.ts(64,1): error TS2322: Type '[]' is not assignable to type '[number, {}]'.
28+
Property '0' is missing in type '[]'.
29+
tests/cases/compiler/tupleTypes.ts(65,1): error TS2322: Type '[number, string]' is not assignable to type '[]'.
30+
Types of property 'pop' are incompatible.
31+
Type '() => string | number' is not assignable to type '() => never'.
32+
Type 'string | number' is not assignable to type 'never'.
33+
Type 'string' is not assignable to type 'never'.
2334

2435

25-
==== tests/cases/compiler/tupleTypes.ts (9 errors) ====
26-
var v1: []; // Error
27-
~~
28-
!!! error TS1122: A tuple type element list cannot be empty.
36+
==== tests/cases/compiler/tupleTypes.ts (12 errors) ====
37+
var v1: [];
2938
var v2: [number];
3039
var v3: [number, string];
3140
var v4: [number, [string, string]];
@@ -40,8 +49,8 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n
4049

4150
t = []; // Error
4251
~
43-
!!! error TS2322: Type 'undefined[]' is not assignable to type '[number, string]'.
44-
!!! error TS2322: Property '0' is missing in type 'undefined[]'.
52+
!!! error TS2322: Type '[]' is not assignable to type '[number, string]'.
53+
!!! error TS2322: Property '0' is missing in type '[]'.
4554
t = [1]; // Error
4655
~
4756
!!! error TS2322: Type '[number]' is not assignable to type '[number, string]'.
@@ -53,6 +62,18 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n
5362
!!! error TS2322: Type 'string' is not assignable to type 'number'.
5463
t = [1, "hello", 2]; // Ok
5564

65+
var et: [];
66+
var et0 = et[0]; // never
67+
var et0: never;
68+
69+
et = []; // Ok
70+
et = [1]; // Error
71+
~~
72+
!!! error TS2322: Type '[number]' is not assignable to type '[]'.
73+
!!! error TS2322: Types of property 'pop' are incompatible.
74+
!!! error TS2322: Type '() => number' is not assignable to type '() => never'.
75+
!!! error TS2322: Type 'number' is not assignable to type 'never'.
76+
5677
var tf: [string, (x: string) => number] = ["hello", x => x.length];
5778

5879
declare function ff<T, U>(a: T, b: [T, (x: T) => U]): U;
@@ -76,12 +97,13 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n
7697
tt = [undefined, undefined];
7798
tt = []; // Error
7899
~~
79-
!!! error TS2322: Type 'undefined[]' is not assignable to type '[number, string]'.
100+
!!! error TS2322: Type '[]' is not assignable to type '[number, string]'.
80101

81102
var a: number[];
82103
var a1: [number, string];
83104
var a2: [number, number];
84105
var a3: [number, {}];
106+
var a4: [];
85107
a = a1; // Error
86108
~
87109
!!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'.
@@ -97,6 +119,7 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n
97119
!!! error TS2322: Type '() => number | {}' is not assignable to type '() => number'.
98120
!!! error TS2322: Type 'number | {}' is not assignable to type 'number'.
99121
!!! error TS2322: Type '{}' is not assignable to type 'number'.
122+
a = a4;
100123
a1 = a2; // Error
101124
~~
102125
!!! error TS2322: Type '[number, number]' is not assignable to type '[number, string]'.
@@ -105,6 +128,20 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n
105128
~~
106129
!!! error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'.
107130
!!! error TS2322: Type '{}' is not assignable to type 'string'.
131+
a1 = a4; // Error
132+
~~
133+
!!! error TS2322: Type '[]' is not assignable to type '[number, string]'.
108134
a3 = a1;
109135
a3 = a2;
136+
a3 = a4; // Error
137+
~~
138+
!!! error TS2322: Type '[]' is not assignable to type '[number, {}]'.
139+
!!! error TS2322: Property '0' is missing in type '[]'.
140+
a4 = a1; // Error
141+
~~
142+
!!! error TS2322: Type '[number, string]' is not assignable to type '[]'.
143+
!!! error TS2322: Types of property 'pop' are incompatible.
144+
!!! error TS2322: Type '() => string | number' is not assignable to type '() => never'.
145+
!!! error TS2322: Type 'string | number' is not assignable to type 'never'.
146+
!!! error TS2322: Type 'string' is not assignable to type 'never'.
110147

tests/baselines/reference/tupleTypes.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//// [tupleTypes.ts]
2-
var v1: []; // Error
2+
var v1: [];
33
var v2: [number];
44
var v3: [number, string];
55
var v4: [number, [string, string]];
@@ -18,6 +18,13 @@ t = [1, "hello"]; // Ok
1818
t = ["hello", 1]; // Error
1919
t = [1, "hello", 2]; // Ok
2020

21+
var et: [];
22+
var et0 = et[0]; // never
23+
var et0: never;
24+
25+
et = []; // Ok
26+
et = [1]; // Error
27+
2128
var tf: [string, (x: string) => number] = ["hello", x => x.length];
2229

2330
declare function ff<T, U>(a: T, b: [T, (x: T) => U]): U;
@@ -45,17 +52,22 @@ var a: number[];
4552
var a1: [number, string];
4653
var a2: [number, number];
4754
var a3: [number, {}];
55+
var a4: [];
4856
a = a1; // Error
4957
a = a2;
5058
a = a3; // Error
59+
a = a4;
5160
a1 = a2; // Error
5261
a1 = a3; // Error
62+
a1 = a4; // Error
5363
a3 = a1;
5464
a3 = a2;
65+
a3 = a4; // Error
66+
a4 = a1; // Error
5567

5668

5769
//// [tupleTypes.js]
58-
var v1; // Error
70+
var v1;
5971
var v2;
6072
var v3;
6173
var v4;
@@ -71,6 +83,11 @@ t = [1]; // Error
7183
t = [1, "hello"]; // Ok
7284
t = ["hello", 1]; // Error
7385
t = [1, "hello", 2]; // Ok
86+
var et;
87+
var et0 = et[0]; // never
88+
var et0;
89+
et = []; // Ok
90+
et = [1]; // Error
7491
var tf = ["hello", function (x) { return x.length; }];
7592
var ff1 = ff("hello", ["foo", function (x) { return x.length; }]);
7693
var ff1;
@@ -92,10 +109,15 @@ var a;
92109
var a1;
93110
var a2;
94111
var a3;
112+
var a4;
95113
a = a1; // Error
96114
a = a2;
97115
a = a3; // Error
116+
a = a4;
98117
a1 = a2; // Error
99118
a1 = a3; // Error
119+
a1 = a4; // Error
100120
a3 = a1;
101121
a3 = a2;
122+
a3 = a4; // Error
123+
a4 = a1; // Error
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [tupleTypesStrictNullChecks.ts]
2+
var et: [] = [];
3+
var et0 = et[0]; // never
4+
var et0: never;
5+
6+
et = []; // Ok
7+
8+
9+
//// [tupleTypesStrictNullChecks.js]
10+
var et = [];
11+
var et0 = et[0]; // never
12+
var et0;
13+
et = []; // Ok

0 commit comments

Comments
 (0)