Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
progress, now it evaluates too slow for b!
  • Loading branch information
KiaraGrouwstra committed Aug 19, 2017
commit e89096db17817e869a25664e362b94ad636ebec4
87 changes: 67 additions & 20 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/// <reference path="moduleNameResolver.ts"/>
/// <reference path="binder.ts"/>
// /// <reference types="node" />
/// <reference types="node" />

// declare var console: Console;
declare var console: Console;

/* @internal */
namespace ts {
Expand Down Expand Up @@ -240,6 +240,7 @@ namespace ts {
const intersectionTypes = createMap<IntersectionType>();
const literalTypes = createMap<LiteralType>();
const indexedAccessTypes = createMap<IndexedAccessType>();
const spreadTypes = createMap<TypeSpreadType>();
const evolvingArrayTypes: EvolvingArrayType[] = [];

const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String);
Expand Down Expand Up @@ -2528,6 +2529,10 @@ namespace ts {
const indexTypeNode = typeToTypeNodeHelper((<IndexedAccessType>type).indexType, context);
return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
}
if (type.flags & TypeFlags.TypeSpread) {
const typeNode = typeToTypeNodeHelper((<TypeSpreadType>type).type, context);
return createTypeSpread(typeNode);
}

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

Expand Down Expand Up @@ -3291,6 +3296,10 @@ namespace ts {
writeType((<IndexedAccessType>type).indexType, TypeFormatFlags.None);
writePunctuation(writer, SyntaxKind.CloseBracketToken);
}
else if (type.flags & TypeFlags.TypeSpread) {
writePunctuation(writer, SyntaxKind.DotDotDotToken);
writeType((<TypeSpreadType>type).type, TypeFormatFlags.None);
}
else {
// Should never get here
// { ... }
Expand Down Expand Up @@ -5383,7 +5392,7 @@ namespace ts {
}

function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: TypeParameter[], typeArguments: Type[]) {
// if (allowSyntheticDefaultImports) console.log("resolveObjectTypeMembers", typeToString(type));
if (allowSyntheticDefaultImports) console.log("resolveObjectTypeMembers", typeToString(type));
let mapper: TypeMapper;
let members: SymbolTable;
let callSignatures: Signature[];
Expand Down Expand Up @@ -7211,6 +7220,39 @@ namespace ts {
return links.resolvedType;
}

function getTypeSpreadTypes(tuple: Type): Type[] {
if (isGenericTupleType(tuple)) {
// Defer the operation by creating a spread type.
const id = "" + tuple.id;
let type = spreadTypes.get(id);
if (!type) {
spreadTypes.set(id, type = createTypeSpreadType(tuple));
}
return [type];
} else {
// const type = getApparentType(nodeType);
if (allowSyntheticDefaultImports) {
console.log("type", typeToString(tuple));
console.log("isTupleLikeType(type)", isTupleLikeType(tuple));
}
if (isTupleLikeType(tuple)) {
// return map(getPropertiesOfType(tuple), getTypeOfSymbol);
return getTupleTypeElementTypes(tuple);
}
else {
// error(typeNode, Diagnostics.Tuple_type_spreads_may_only_be_created_from_tuple_types);
console.log("not a tuple, don't resolve?");
return [];
}
}
}

function isGenericTupleType(type: Type): boolean {
return type.flags & TypeFlags.TypeVariable ? true :
type.flags & TypeFlags.UnionOrIntersection ? forEach((<UnionOrIntersectionType>type).types, isGenericTupleType) :
false;
}

function getTupleTypeElementTypes(type: Type): Type[] {
Debug.assert(isTupleLikeType(type));
const types = [];
Expand All @@ -7224,24 +7266,11 @@ namespace ts {

function getTypeFromTupleElement(node: TypeNode | TypeSpreadTypeNode): Type | Type[] {
if (node.kind === SyntaxKind.TypeSpread) {
const typeNode: TypeNode = (node as TypeSpreadTypeNode).type;
const type = getApparentType(getTypeFromTypeNode(typeNode as TypeNode));
// const nodeType = getTypeFromTypeNode(typeNode as TypeNode);
// const type = getApparentType(nodeType);
if (allowSyntheticDefaultImports) {
// console.log("nodeType", typeToString(nodeType));
// console.log("type", typeToString(type));
// console.log("isTupleLikeType(nodeType)", isTupleLikeType(nodeType));
// console.log("isTupleLikeType(type)", isTupleLikeType(type));
}
if (isTupleLikeType(type)) {
// return map(getPropertiesOfType(type), getTypeOfSymbol);
return getTupleTypeElementTypes(type);
}
else {
error(typeNode, Diagnostics.Tuple_type_spreads_may_only_be_created_from_tuple_types);
return [];
const links = getNodeLinks(node);
if (!links.resolvedType) {
links.resolvedType = getTypeFromTypeNode((node as TypeSpreadTypeNode).type)
}
return getTypeSpreadTypes(links.resolvedType);
}
else {
return getTypeFromTypeNode(node as TypeNode);
Expand Down Expand Up @@ -7585,6 +7614,12 @@ namespace ts {
return type;
}

function createTypeSpreadType(tuple: Type) {
const type = <TypeSpreadType>createType(TypeFlags.TypeSpread);
type.type = tuple;
return type;
}

function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode, cacheSymbol: boolean) {
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? <ElementAccessExpression>accessNode : undefined;
const propName = indexType.flags & TypeFlags.StringOrNumberLiteral ?
Expand Down Expand Up @@ -8400,6 +8435,9 @@ namespace ts {
if (type.flags & TypeFlags.IndexedAccess) {
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
}
// if (type.flags & TypeFlags.TypeSpread) {
// return getTypeSpreadTypes(instantiateType((<TypeSpreadType>type).type, mapper));
// }
return type;
}

Expand Down Expand Up @@ -18799,6 +18837,13 @@ namespace ts {
forEach(node.elementTypes, checkSourceElement);
}

function checkTypeSpread(node: TypeSpreadTypeNode) {
const type = getApparentType(getTypeFromTypeNode(node.type as TypeNode));
if (!isArrayLikeType(type)) { // isTupleLikeType
grammarErrorOnNode(node, Diagnostics.Tuple_type_spreads_may_only_be_created_from_tuple_types);
}
}

function checkUnionOrIntersectionType(node: UnionOrIntersectionTypeNode) {
forEach(node.types, checkSourceElement);
}
Expand Down Expand Up @@ -22334,6 +22379,8 @@ namespace ts {
return checkArrayType(<ArrayTypeNode>node);
case SyntaxKind.TupleType:
return checkTupleType(<TupleTypeNode>node);
case SyntaxKind.TypeSpread:
return checkTypeSpread(<TypeSpreadTypeNode>node);
case SyntaxKind.UnionType:
case SyntaxKind.IntersectionType:
return checkUnionOrIntersectionType(<UnionOrIntersectionTypeNode>node);
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3146,6 +3146,7 @@ namespace ts {
NonPrimitive = 1 << 24, // intrinsic object type
/* @internal */
JsxAttributes = 1 << 25, // Jsx attributes type
TypeSpread = 1 << 26, // spread in tuple types

/* @internal */
Nullable = Undefined | Null,
Expand Down Expand Up @@ -3393,6 +3394,11 @@ namespace ts {
constraint?: Type;
}

// type spread types (TypeFlags.TypeSpread)
export interface TypeSpreadType extends TypeVariable {
type: Type;
}

// keyof T types (TypeFlags.Index)
export interface IndexType extends Type {
type: TypeVariable | UnionOrIntersectionType;
Expand Down
10 changes: 0 additions & 10 deletions tests/baselines/reference/tupleTypeSpread.errors.txt

This file was deleted.

11 changes: 11 additions & 0 deletions tests/baselines/reference/tupleTypeSpread.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,14 @@
type a = [1, ...[2]];
>a : Symbol(a, Decl(tupleTypeSpread.ts, 0, 0))

type Combine<Head, Tail extends any[]> = [Head, ...Tail];
>Combine : Symbol(Combine, Decl(tupleTypeSpread.ts, 0, 21))
>Head : Symbol(Head, Decl(tupleTypeSpread.ts, 1, 13))
>Tail : Symbol(Tail, Decl(tupleTypeSpread.ts, 1, 18))
>Head : Symbol(Head, Decl(tupleTypeSpread.ts, 1, 13))
>Tail : Symbol(Tail, Decl(tupleTypeSpread.ts, 1, 18))

type b = Combine<1, [2, 3]>;
>b : Symbol(b, Decl(tupleTypeSpread.ts, 1, 57))
>Combine : Symbol(Combine, Decl(tupleTypeSpread.ts, 0, 21))

11 changes: 11 additions & 0 deletions tests/baselines/reference/tupleTypeSpread.types
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,14 @@
type a = [1, ...[2]];
>a : [1, 2]

type Combine<Head, Tail extends any[]> = [Head, ...Tail];
>Combine : [Head, ...Tail]
>Head : Head
>Tail : Tail
>Head : Head
>Tail : Tail

type b = Combine<1, [2, 3]>;
>b : [1, ...Tail]
>Combine : [Head, ...Tail]