Typescript - Tuples can include rest elements (#8805)

This commit is contained in:
Retsam 2018-10-08 12:32:31 -04:00 committed by Brian Ng
parent 4b8cb75b74
commit 08454ece46
9 changed files with 210 additions and 1 deletions

View File

@ -246,6 +246,11 @@ export function TSOptionalType(node) {
this.token("?"); this.token("?");
} }
export function TSRestType(node) {
this.token("...");
this.print(node.typeAnnotation, node);
}
export function TSUnionType(node) { export function TSUnionType(node) {
this.tsPrintUnionOrIntersectionType(node, "|"); this.tsPrintUnionOrIntersectionType(node, "|");
} }

View File

@ -0,0 +1 @@
let x: [string, ...number[]]

View File

@ -0,0 +1 @@
let x: [string, ...number[]];

View File

@ -511,7 +511,16 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} }
tsParseTupleElementType(): N.TsType { tsParseTupleElementType(): N.TsType {
// parses `...TsType[]`
if (this.match(tt.ellipsis)) {
const restNode: N.TsRestType = this.startNode();
this.next(); // skips ellipsis
restNode.typeAnnotation = this.tsParseType();
return this.finishNode(restNode, "TSRestType");
}
const type = this.tsParseType(); const type = this.tsParseType();
// parses `TsType?`
if (this.eat(tt.question)) { if (this.eat(tt.question)) {
const optionalTypeNode: N.TsOptionalType = this.startNodeAtNode(type); const optionalTypeNode: N.TsOptionalType = this.startNodeAtNode(type);
optionalTypeNode.typeAnnotation = type; optionalTypeNode.typeAnnotation = type;

View File

@ -1105,6 +1105,7 @@ export type TsType =
| TsArrayType | TsArrayType
| TsTupleType | TsTupleType
| TsOptionalType | TsOptionalType
| TsRestType
| TsUnionOrIntersectionType | TsUnionOrIntersectionType
| TsConditionalType | TsConditionalType
| TsInferType | TsInferType
@ -1190,6 +1191,11 @@ export type TsOptionalType = TsTypeBase & {
typeAnnotation: TsType, typeAnnotation: TsType,
}; };
export type TsRestType = TsTypeBase & {
type: "TSRestType",
typeAnnotation: TsType,
};
export type TsUnionOrIntersectionType = TsUnionType | TsIntersectionType; export type TsUnionOrIntersectionType = TsUnionType | TsIntersectionType;
export type TsUnionOrIntersectionTypeBase = TsTypeBase & { export type TsUnionOrIntersectionTypeBase = TsTypeBase & {

View File

@ -0,0 +1 @@
let x: [string, ...number[]]

View File

@ -0,0 +1,178 @@
{
"type": "File",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 28
}
},
"program": {
"type": "Program",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 28
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 28
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 28
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 28
},
"identifierName": "x"
},
"name": "x",
"typeAnnotation": {
"type": "TSTypeAnnotation",
"start": 5,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 28
}
},
"typeAnnotation": {
"type": "TSTupleType",
"start": 7,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 28
}
},
"elementTypes": [
{
"type": "TSStringKeyword",
"start": 8,
"end": 14,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 14
}
}
},
{
"type": "TSRestType",
"start": 16,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 1,
"column": 27
}
},
"typeAnnotation": {
"type": "TSArrayType",
"start": 19,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 19
},
"end": {
"line": 1,
"column": 27
}
},
"elementType": {
"type": "TSNumberKeyword",
"start": 19,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 19
},
"end": {
"line": 1,
"column": 25
}
}
}
}
}
]
}
}
},
"init": null
}
],
"kind": "let"
}
],
"directives": []
}
}

View File

@ -1 +1 @@
function foo(...args: [number, string?]) {} function foo(...args: [number, string?, ...number[]]) {}

View File

@ -221,6 +221,14 @@ defineType("TSOptionalType", {
}, },
}); });
defineType("TSRestType", {
aliases: ["TSType"],
visitor: ["typeAnnotation"],
fields: {
typeAnnotation: validateType("TSType"),
},
});
const unionOrIntersection = { const unionOrIntersection = {
aliases: ["TSType"], aliases: ["TSType"],
visitor: ["types"], visitor: ["types"],