Skip to content

Commit 8650263

Browse files
authored
feat: add support for mixed labeled and unlabeled tuple types (#22)
* feat: add support for mixed labeled and unlabeled tuple types * chore: use tabs instead of space indent * refactor: remove unused var
1 parent 5cf669b commit 8650263

File tree

4 files changed

+159
-10
lines changed

4 files changed

+159
-10
lines changed

src/error.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export const TypeScriptError = {
4848
'You can either wrap the instantiation expression in parentheses, or delete the type arguments.',
4949
InvalidTupleMemberLabel: 'Tuple members must be labeled with a simple identifier.',
5050
MissingInterfaceName: "'interface' declarations must be followed by an identifier.",
51-
MixedLabeledAndUnlabeledElements: 'Tuple members must all have names or all not have names.',
5251
NonAbstractClassHasAbstractMethod: 'Abstract methods can only appear within an abstract class.',
5352
NonClassMethodPropertyHasAbstractModifer:
5453
"'abstract' modifier can only appear on a class, method, or property declaration.",

src/index.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,7 +1692,6 @@ export function tsPlugin(options?: {
16921692
// Validate the elementTypes to ensure that no mandatory elements
16931693
// follow optional elements
16941694
let seenOptionalElement = false;
1695-
let labeledElements: boolean | null = null;
16961695
node.elementTypes.forEach((elementNode) => {
16971696
const { type } = elementNode;
16981697

@@ -1709,16 +1708,8 @@ export function tsPlugin(options?: {
17091708
(type === 'TSNamedTupleMember' && elementNode.optional) || type === 'TSOptionalType';
17101709

17111710
// When checking labels, check the argument of the spread operator
1712-
let checkType = type;
17131711
if (type === 'TSRestType') {
17141712
elementNode = elementNode.typeAnnotation;
1715-
checkType = elementNode.type;
1716-
}
1717-
1718-
const isLabeled = checkType === 'TSNamedTupleMember';
1719-
labeledElements ??= isLabeled;
1720-
if (labeledElements !== isLabeled) {
1721-
this.raise(elementNode.start, TypeScriptError.MixedLabeledAndUnlabeledElements);
17221713
}
17231714
});
17241715

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
{
2+
"type": "Program",
3+
"start": 0,
4+
"end": 37,
5+
"loc": {
6+
"start": {
7+
"line": 1,
8+
"column": 0
9+
},
10+
"end": {
11+
"line": 2,
12+
"column": 0
13+
}
14+
},
15+
"body": [
16+
{
17+
"type": "TSTypeAliasDeclaration",
18+
"start": 0,
19+
"end": 36,
20+
"loc": {
21+
"start": {
22+
"line": 1,
23+
"column": 0
24+
},
25+
"end": {
26+
"line": 1,
27+
"column": 36
28+
}
29+
},
30+
"id": {
31+
"type": "Identifier",
32+
"start": 5,
33+
"end": 6,
34+
"loc": {
35+
"start": {
36+
"line": 1,
37+
"column": 5
38+
},
39+
"end": {
40+
"line": 1,
41+
"column": 6
42+
}
43+
},
44+
"name": "A"
45+
},
46+
"typeAnnotation": {
47+
"type": "TSTupleType",
48+
"start": 9,
49+
"end": 35,
50+
"loc": {
51+
"start": {
52+
"line": 1,
53+
"column": 9
54+
},
55+
"end": {
56+
"line": 1,
57+
"column": 35
58+
}
59+
},
60+
"elementTypes": [
61+
{
62+
"type": "TSNamedTupleMember",
63+
"start": 10,
64+
"end": 21,
65+
"loc": {
66+
"start": {
67+
"line": 1,
68+
"column": 10
69+
},
70+
"end": {
71+
"line": 1,
72+
"column": 21
73+
}
74+
},
75+
"optional": false,
76+
"label": {
77+
"type": "Identifier",
78+
"start": 10,
79+
"end": 13,
80+
"loc": {
81+
"start": {
82+
"line": 1,
83+
"column": 10
84+
},
85+
"end": {
86+
"line": 1,
87+
"column": 13
88+
}
89+
},
90+
"name": "foo"
91+
},
92+
"elementType": {
93+
"type": "TSStringKeyword",
94+
"start": 15,
95+
"end": 21,
96+
"loc": {
97+
"start": {
98+
"line": 1,
99+
"column": 15
100+
},
101+
"end": {
102+
"line": 1,
103+
"column": 21
104+
}
105+
}
106+
}
107+
},
108+
{
109+
"type": "TSRestType",
110+
"start": 23,
111+
"end": 34,
112+
"loc": {
113+
"start": {
114+
"line": 1,
115+
"column": 23
116+
},
117+
"end": {
118+
"line": 1,
119+
"column": 34
120+
}
121+
},
122+
"typeAnnotation": {
123+
"type": "TSArrayType",
124+
"start": 26,
125+
"end": 34,
126+
"loc": {
127+
"start": {
128+
"line": 1,
129+
"column": 26
130+
},
131+
"end": {
132+
"line": 1,
133+
"column": 34
134+
}
135+
},
136+
"elementType": {
137+
"type": "TSNumberKeyword",
138+
"start": 26,
139+
"end": 32,
140+
"loc": {
141+
"start": {
142+
"line": 1,
143+
"column": 26
144+
},
145+
"end": {
146+
"line": 1,
147+
"column": 32
148+
}
149+
}
150+
}
151+
}
152+
}
153+
]
154+
}
155+
}
156+
],
157+
"sourceType": "module"
158+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
type A = [foo: string, ...number[]];

0 commit comments

Comments
 (0)