Skip to content

Commit e89096d

Browse files
progress, now it evaluates too slow for b!
1 parent 17310a8 commit e89096d

File tree

5 files changed

+95
-30
lines changed

5 files changed

+95
-30
lines changed

src/compiler/checker.ts

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/// <reference path="moduleNameResolver.ts"/>
22
/// <reference path="binder.ts"/>
3-
// /// <reference types="node" />
3+
/// <reference types="node" />
44

5-
// declare var console: Console;
5+
declare var console: Console;
66

77
/* @internal */
88
namespace ts {
@@ -240,6 +240,7 @@ namespace ts {
240240
const intersectionTypes = createMap<IntersectionType>();
241241
const literalTypes = createMap<LiteralType>();
242242
const indexedAccessTypes = createMap<IndexedAccessType>();
243+
const spreadTypes = createMap<TypeSpreadType>();
243244
const evolvingArrayTypes: EvolvingArrayType[] = [];
244245

245246
const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String);
@@ -2528,6 +2529,10 @@ namespace ts {
25282529
const indexTypeNode = typeToTypeNodeHelper((<IndexedAccessType>type).indexType, context);
25292530
return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
25302531
}
2532+
if (type.flags & TypeFlags.TypeSpread) {
2533+
const typeNode = typeToTypeNodeHelper((<TypeSpreadType>type).type, context);
2534+
return createTypeSpread(typeNode);
2535+
}
25312536

25322537
Debug.fail("Should be unreachable.");
25332538

@@ -3291,6 +3296,10 @@ namespace ts {
32913296
writeType((<IndexedAccessType>type).indexType, TypeFormatFlags.None);
32923297
writePunctuation(writer, SyntaxKind.CloseBracketToken);
32933298
}
3299+
else if (type.flags & TypeFlags.TypeSpread) {
3300+
writePunctuation(writer, SyntaxKind.DotDotDotToken);
3301+
writeType((<TypeSpreadType>type).type, TypeFormatFlags.None);
3302+
}
32943303
else {
32953304
// Should never get here
32963305
// { ... }
@@ -5383,7 +5392,7 @@ namespace ts {
53835392
}
53845393

53855394
function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: TypeParameter[], typeArguments: Type[]) {
5386-
// if (allowSyntheticDefaultImports) console.log("resolveObjectTypeMembers", typeToString(type));
5395+
if (allowSyntheticDefaultImports) console.log("resolveObjectTypeMembers", typeToString(type));
53875396
let mapper: TypeMapper;
53885397
let members: SymbolTable;
53895398
let callSignatures: Signature[];
@@ -7211,6 +7220,39 @@ namespace ts {
72117220
return links.resolvedType;
72127221
}
72137222

7223+
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];
7232+
} else {
7233+
// const type = getApparentType(nodeType);
7234+
if (allowSyntheticDefaultImports) {
7235+
console.log("type", typeToString(tuple));
7236+
console.log("isTupleLikeType(type)", isTupleLikeType(tuple));
7237+
}
7238+
if (isTupleLikeType(tuple)) {
7239+
// return map(getPropertiesOfType(tuple), getTypeOfSymbol);
7240+
return getTupleTypeElementTypes(tuple);
7241+
}
7242+
else {
7243+
// error(typeNode, Diagnostics.Tuple_type_spreads_may_only_be_created_from_tuple_types);
7244+
console.log("not a tuple, don't resolve?");
7245+
return [];
7246+
}
7247+
}
7248+
}
7249+
7250+
function isGenericTupleType(type: Type): boolean {
7251+
return type.flags & TypeFlags.TypeVariable ? true :
7252+
type.flags & TypeFlags.UnionOrIntersection ? forEach((<UnionOrIntersectionType>type).types, isGenericTupleType) :
7253+
false;
7254+
}
7255+
72147256
function getTupleTypeElementTypes(type: Type): Type[] {
72157257
Debug.assert(isTupleLikeType(type));
72167258
const types = [];
@@ -7224,24 +7266,11 @@ namespace ts {
72247266

72257267
function getTypeFromTupleElement(node: TypeNode | TypeSpreadTypeNode): Type | Type[] {
72267268
if (node.kind === SyntaxKind.TypeSpread) {
7227-
const typeNode: TypeNode = (node as TypeSpreadTypeNode).type;
7228-
const type = getApparentType(getTypeFromTypeNode(typeNode as TypeNode));
7229-
// const nodeType = getTypeFromTypeNode(typeNode as TypeNode);
7230-
// const type = getApparentType(nodeType);
7231-
if (allowSyntheticDefaultImports) {
7232-
// console.log("nodeType", typeToString(nodeType));
7233-
// console.log("type", typeToString(type));
7234-
// console.log("isTupleLikeType(nodeType)", isTupleLikeType(nodeType));
7235-
// console.log("isTupleLikeType(type)", isTupleLikeType(type));
7236-
}
7237-
if (isTupleLikeType(type)) {
7238-
// return map(getPropertiesOfType(type), getTypeOfSymbol);
7239-
return getTupleTypeElementTypes(type);
7240-
}
7241-
else {
7242-
error(typeNode, Diagnostics.Tuple_type_spreads_may_only_be_created_from_tuple_types);
7243-
return [];
7269+
const links = getNodeLinks(node);
7270+
if (!links.resolvedType) {
7271+
links.resolvedType = getTypeFromTypeNode((node as TypeSpreadTypeNode).type)
72447272
}
7273+
return getTypeSpreadTypes(links.resolvedType);
72457274
}
72467275
else {
72477276
return getTypeFromTypeNode(node as TypeNode);
@@ -7585,6 +7614,12 @@ namespace ts {
75857614
return type;
75867615
}
75877616

7617+
function createTypeSpreadType(tuple: Type) {
7618+
const type = <TypeSpreadType>createType(TypeFlags.TypeSpread);
7619+
type.type = tuple;
7620+
return type;
7621+
}
7622+
75887623
function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode, cacheSymbol: boolean) {
75897624
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? <ElementAccessExpression>accessNode : undefined;
75907625
const propName = indexType.flags & TypeFlags.StringOrNumberLiteral ?
@@ -8400,6 +8435,9 @@ namespace ts {
84008435
if (type.flags & TypeFlags.IndexedAccess) {
84018436
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
84028437
}
8438+
// if (type.flags & TypeFlags.TypeSpread) {
8439+
// return getTypeSpreadTypes(instantiateType((<TypeSpreadType>type).type, mapper));
8440+
// }
84038441
return type;
84048442
}
84058443

@@ -18799,6 +18837,13 @@ namespace ts {
1879918837
forEach(node.elementTypes, checkSourceElement);
1880018838
}
1880118839

18840+
function checkTypeSpread(node: TypeSpreadTypeNode) {
18841+
const type = getApparentType(getTypeFromTypeNode(node.type as TypeNode));
18842+
if (!isArrayLikeType(type)) { // isTupleLikeType
18843+
grammarErrorOnNode(node, Diagnostics.Tuple_type_spreads_may_only_be_created_from_tuple_types);
18844+
}
18845+
}
18846+
1880218847
function checkUnionOrIntersectionType(node: UnionOrIntersectionTypeNode) {
1880318848
forEach(node.types, checkSourceElement);
1880418849
}
@@ -22334,6 +22379,8 @@ namespace ts {
2233422379
return checkArrayType(<ArrayTypeNode>node);
2233522380
case SyntaxKind.TupleType:
2233622381
return checkTupleType(<TupleTypeNode>node);
22382+
case SyntaxKind.TypeSpread:
22383+
return checkTypeSpread(<TypeSpreadTypeNode>node);
2233722384
case SyntaxKind.UnionType:
2233822385
case SyntaxKind.IntersectionType:
2233922386
return checkUnionOrIntersectionType(<UnionOrIntersectionTypeNode>node);

src/compiler/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3146,6 +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
31493150

31503151
/* @internal */
31513152
Nullable = Undefined | Null,
@@ -3393,6 +3394,11 @@ namespace ts {
33933394
constraint?: Type;
33943395
}
33953396

3397+
// type spread types (TypeFlags.TypeSpread)
3398+
export interface TypeSpreadType extends TypeVariable {
3399+
type: Type;
3400+
}
3401+
33963402
// keyof T types (TypeFlags.Index)
33973403
export interface IndexType extends Type {
33983404
type: TypeVariable | UnionOrIntersectionType;

tests/baselines/reference/tupleTypeSpread.errors.txt

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/baselines/reference/tupleTypeSpread.symbols

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,14 @@
22
type a = [1, ...[2]];
33
>a : Symbol(a, Decl(tupleTypeSpread.ts, 0, 0))
44

5+
type Combine<Head, Tail extends any[]> = [Head, ...Tail];
6+
>Combine : Symbol(Combine, Decl(tupleTypeSpread.ts, 0, 21))
7+
>Head : Symbol(Head, Decl(tupleTypeSpread.ts, 1, 13))
8+
>Tail : Symbol(Tail, Decl(tupleTypeSpread.ts, 1, 18))
9+
>Head : Symbol(Head, Decl(tupleTypeSpread.ts, 1, 13))
10+
>Tail : Symbol(Tail, Decl(tupleTypeSpread.ts, 1, 18))
11+
12+
type b = Combine<1, [2, 3]>;
13+
>b : Symbol(b, Decl(tupleTypeSpread.ts, 1, 57))
14+
>Combine : Symbol(Combine, Decl(tupleTypeSpread.ts, 0, 21))
15+

tests/baselines/reference/tupleTypeSpread.types

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,14 @@
22
type a = [1, ...[2]];
33
>a : [1, 2]
44

5+
type Combine<Head, Tail extends any[]> = [Head, ...Tail];
6+
>Combine : [Head, ...Tail]
7+
>Head : Head
8+
>Tail : Tail
9+
>Head : Head
10+
>Tail : Tail
11+
12+
type b = Combine<1, [2, 3]>;
13+
>b : [1, ...Tail]
14+
>Combine : [Head, ...Tail]
15+

0 commit comments

Comments
 (0)