Skip to content

Commit 66065d0

Browse files
test working
1 parent 4dad31c commit 66065d0

File tree

6 files changed

+61
-56
lines changed

6 files changed

+61
-56
lines changed

src/compiler/checker.ts

Lines changed: 39 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
/// <reference path="moduleNameResolver.ts"/>
22
/// <reference path="binder.ts"/>
3-
/// <reference types="node" />
4-
5-
declare var console: Console;
63

74
/* @internal */
85
namespace ts {
@@ -240,7 +237,6 @@ namespace ts {
240237
const intersectionTypes = createMap<IntersectionType>();
241238
const literalTypes = createMap<LiteralType>();
242239
const indexedAccessTypes = createMap<IndexedAccessType>();
243-
const spreadTypes = createMap<TypeSpreadType>();
244240
const evolvingArrayTypes: EvolvingArrayType[] = [];
245241

246242
const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String);
@@ -2529,9 +2525,9 @@ namespace ts {
25292525
const indexTypeNode = typeToTypeNodeHelper((<IndexedAccessType>type).indexType, context);
25302526
return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
25312527
}
2532-
if (type.flags & TypeFlags.TypeSpread) {
2533-
const typeNode = typeToTypeNodeHelper((<TypeSpreadType>type).type, context);
2534-
return createTypeSpread(typeNode);
2528+
if (type.flags & TypeFlags.SpreadTuple) {
2529+
const typeNodes = map((<SpreadTupleType>type).elements, (tp: Type) => typeToTypeNodeHelper(tp, context));
2530+
return createTupleTypeNode(typeNodes, (<SpreadTupleType>type).idxIsSpread);
25352531
}
25362532

25372533
Debug.fail("Should be unreachable.");
@@ -3296,9 +3292,11 @@ namespace ts {
32963292
writeType((<IndexedAccessType>type).indexType, TypeFormatFlags.None);
32973293
writePunctuation(writer, SyntaxKind.CloseBracketToken);
32983294
}
3299-
else if (type.flags & TypeFlags.TypeSpread) {
3295+
else if (type.flags & TypeFlags.SpreadTuple) {
3296+
writePunctuation(writer, SyntaxKind.OpenBracketToken);
33003297
writePunctuation(writer, SyntaxKind.DotDotDotToken);
3301-
writeType((<TypeSpreadType>type).type, TypeFormatFlags.None);
3298+
writeTypeList((<SpreadTupleType>type).elements, SyntaxKind.CommaToken, (<SpreadTupleType>type).idxIsSpread);
3299+
writePunctuation(writer, SyntaxKind.CloseBracketToken);
33023300
}
33033301
else {
33043302
// Should never get here
@@ -3312,7 +3310,7 @@ namespace ts {
33123310
}
33133311

33143312

3315-
function writeTypeList(types: Type[], delimiter: SyntaxKind) {
3313+
function writeTypeList(types: Type[], delimiter: SyntaxKind, idxIsSpread: boolean[] = []) {
33163314
for (let i = 0; i < types.length; i++) {
33173315
if (i > 0) {
33183316
if (delimiter !== SyntaxKind.CommaToken) {
@@ -3321,6 +3319,9 @@ namespace ts {
33213319
writePunctuation(writer, delimiter);
33223320
writeSpace(writer);
33233321
}
3322+
if (idxIsSpread[i]) {
3323+
writePunctuation(writer, SyntaxKind.DotDotDotToken);
3324+
}
33243325
writeType(types[i], delimiter === SyntaxKind.CommaToken ? TypeFormatFlags.None : TypeFormatFlags.InElementType);
33253326
}
33263327
}
@@ -5392,7 +5393,6 @@ namespace ts {
53925393
}
53935394

53945395
function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: TypeParameter[], typeArguments: Type[]) {
5395-
if (allowSyntheticDefaultImports) console.log("resolveObjectTypeMembers", typeToString(type));
53965396
let mapper: TypeMapper;
53975397
let members: SymbolTable;
53985398
let callSignatures: Signature[];
@@ -7215,36 +7215,22 @@ namespace ts {
72157215
function getTypeFromTupleTypeNode(node: TupleTypeNode): Type {
72167216
const links = getNodeLinks(node);
72177217
if (!links.resolvedType) {
7218-
links.resolvedType = createTupleType(flatMap(node.elementTypes, getTypeFromTupleElement));
7218+
links.resolvedType = getTypeForTupleNode(node);
72197219
}
72207220
return links.resolvedType;
72217221
}
72227222

7223+
function getSpreadTupleTypes(elements: Type[], idxIsSpread: boolean[]): Type {
7224+
return createTupleType(flatMap(elements, (tp: Type, i: number) => idxIsSpread[i] ? getTypeSpreadTypes(tp) : tp));
7225+
}
7226+
72237227
function getTypeSpreadTypes(tuple: Type): Type[] {
7224-
if (isGenericTupleType(tuple)) {
7225-
// Defer the operation by creating a spread type.
7226-
const id = "" + tuple.id;
7227-
let type = spreadTypes.get(id);
7228-
if (!type) {
7229-
spreadTypes.set(id, type = createTypeSpreadType(tuple));
7230-
}
7231-
return [type];
7228+
if (isTupleLikeType(tuple)) {
7229+
return getTupleTypeElementTypes(tuple);
72327230
}
72337231
else {
7234-
// const type = getApparentType(nodeType);
7235-
if (allowSyntheticDefaultImports) {
7236-
console.log("type", typeToString(tuple));
7237-
console.log("isTupleLikeType(type)", isTupleLikeType(tuple));
7238-
}
7239-
if (isTupleLikeType(tuple)) {
7240-
// return map(getPropertiesOfType(tuple), getTypeOfSymbol);
7241-
return getTupleTypeElementTypes(tuple);
7242-
}
7243-
else {
7244-
// error(typeNode, Diagnostics.Tuple_type_spreads_may_only_be_created_from_tuple_types);
7245-
console.log("not a tuple, don't resolve?");
7246-
return [];
7247-
}
7232+
// console.error("not a tuple, don't resolve?");
7233+
return [];
72487234
}
72497235
}
72507236

@@ -7254,6 +7240,18 @@ namespace ts {
72547240
false;
72557241
}
72567242

7243+
function getTypeForTupleNode(node: TupleTypeNode): Type {
7244+
if (some(node.elementTypes, (n: TypeNode) => n.kind === SyntaxKind.TypeSpread &&
7245+
isGenericTupleType(getTypeFromTypeNode((n as TypeSpreadTypeNode).type)))) {
7246+
const elements = map(node.elementTypes, (n: TypeNode) => getTypeFromTypeNode(n.kind === SyntaxKind.TypeSpread ? (n as TypeSpreadTypeNode).type : n));
7247+
const idxIsSpread = map(node.elementTypes, (n: TypeNode) => n.kind === SyntaxKind.TypeSpread);
7248+
return createTupleSpreadType(elements, idxIsSpread);
7249+
}
7250+
else {
7251+
return createTupleType(flatMap(node.elementTypes, getTypeFromTupleElement));
7252+
}
7253+
}
7254+
72577255
function getTupleTypeElementTypes(type: Type): Type[] {
72587256
Debug.assert(isTupleLikeType(type));
72597257
const types = [];
@@ -7615,10 +7613,10 @@ namespace ts {
76157613
return type;
76167614
}
76177615

7618-
function createTypeSpreadType(tuple: Type) {
7619-
console.log("createTypeSpreadType");
7620-
const type = <TypeSpreadType>createType(TypeFlags.TypeSpread);
7621-
type.type = tuple;
7616+
function createTupleSpreadType(elements: Type[], idxIsSpread: boolean[]) {
7617+
const type = <SpreadTupleType>createType(TypeFlags.SpreadTuple);
7618+
type.elements = elements;
7619+
type.idxIsSpread = idxIsSpread;
76227620
return type;
76237621
}
76247622

@@ -8437,9 +8435,9 @@ namespace ts {
84378435
if (type.flags & TypeFlags.IndexedAccess) {
84388436
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
84398437
}
8440-
// if (type.flags & TypeFlags.TypeSpread) {
8441-
// return getTypeSpreadTypes(instantiateType((<TypeSpreadType>type).type, mapper));
8442-
// }
8438+
if (type.flags & TypeFlags.SpreadTuple) {
8439+
return getSpreadTupleTypes(instantiateTypes((<SpreadTupleType>type).elements, mapper), (<SpreadTupleType>type).idxIsSpread);
8440+
}
84438441
return type;
84448442
}
84458443

@@ -18841,20 +18839,12 @@ namespace ts {
1884118839

1884218840
function checkTypeSpreadTypeNode(node: TypeSpreadTypeNode) {
1884318841
checkSourceElement(node.type);
18844-
// checkTypeSpreadType(<TypeSpreadType> getTypeFromTypeNode(node.type), node);
1884518842
const type = getApparentType(getTypeFromTypeNode(node.type));
1884618843
if (!isArrayLikeType(type)) { // isTupleLikeType
1884718844
grammarErrorOnNode(node, Diagnostics.Tuple_type_spreads_may_only_be_created_from_tuple_types);
1884818845
}
1884918846
}
1885018847

18851-
// function checkTypeSpreadType(spread: TypeSpreadType, node: TypeSpreadTypeNode) {
18852-
// const type = getApparentType(spread.type);
18853-
// if (!isArrayLikeType(type)) { // isTupleLikeType
18854-
// grammarErrorOnNode(node, Diagnostics.Tuple_type_spreads_may_only_be_created_from_tuple_types);
18855-
// }
18856-
// }
18857-
1885818848
function checkUnionOrIntersectionType(node: UnionOrIntersectionTypeNode) {
1885918849
forEach(node.types, checkSourceElement);
1886018850
}

src/compiler/factory.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,10 @@ namespace ts {
674674
: node;
675675
}
676676

677-
export function createTupleTypeNode(elementTypes: ReadonlyArray<TypeNode>) {
677+
export function createTupleTypeNode(elementTypes: ReadonlyArray<TypeNode>, idxIsSpread: boolean[] = []) {
678678
const node = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode;
679-
node.elementTypes = createNodeArray(elementTypes);
679+
const elements = map(elementTypes, (type: TypeNode, idx: number) => idxIsSpread[idx] ? createTypeSpread(type) : type);
680+
node.elementTypes = createNodeArray(elements);
680681
return node;
681682
}
682683

src/compiler/types.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3146,7 +3146,7 @@ namespace ts {
31463146
NonPrimitive = 1 << 24, // intrinsic object type
31473147
/* @internal */
31483148
JsxAttributes = 1 << 25, // Jsx attributes type
3149-
TypeSpread = 1 << 26, // spread in tuple types
3149+
SpreadTuple = 1 << 26, // tuple types containing spreads
31503150

31513151
/* @internal */
31523152
Nullable = Undefined | Null,
@@ -3394,9 +3394,10 @@ namespace ts {
33943394
constraint?: Type;
33953395
}
33963396

3397-
// type spread types (TypeFlags.TypeSpread)
3398-
export interface TypeSpreadType extends Type {
3399-
type: Type;
3397+
// spread tuple types (TypeFlags.SpreadTuple)
3398+
export interface SpreadTupleType extends Type {
3399+
elements: Type[];
3400+
idxIsSpread: boolean[];
34003401
}
34013402

34023403
// keyof T types (TypeFlags.Index)

tests/baselines/reference/tupleTypeSpread.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ type Combine<Head, Tail extends any[]> = [Head, ...Tail];
1010
>Tail : Tail
1111

1212
type b = Combine<1, [2, 3]>;
13-
>b : [1, ...Tail]
13+
>b : [1, 2, 3]
1414
>Combine : [Head, ...Tail]
1515

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
tests/cases/compiler/tupleTypeSpreadErrors.ts(1,32): error TS2714: Tuple type spreads may only be created from tuple types.
2+
3+
4+
==== tests/cases/compiler/tupleTypeSpreadErrors.ts (1 errors) ====
5+
type Boom<T extends string> = [...T];
6+
~~~~
7+
!!! error TS2714: Tuple type spreads may only be created from tuple types.
8+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//// [tupleTypeSpreadErrors.ts]
2+
type Boom<T extends string> = [...T];
3+
4+
5+
//// [tupleTypeSpreadErrors.js]

0 commit comments

Comments
 (0)