Skip to content

Commit a17bd02

Browse files
committed
Associate type alias names with union, intersection and literal types
1 parent 7d1c2fc commit a17bd02

2 files changed

Lines changed: 36 additions & 18 deletions

File tree

src/compiler/checker.ts

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2133,6 +2133,10 @@ namespace ts {
21332133
else if (type.flags & TypeFlags.Tuple) {
21342134
writeTupleType(<TupleType>type);
21352135
}
2136+
else if (type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol) {
2137+
const typeArguments = type.aliasTypeArguments;
2138+
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, flags);
2139+
}
21362140
else if (type.flags & TypeFlags.UnionOrIntersection) {
21372141
writeUnionOrIntersectionType(<UnionOrIntersectionType>type, flags);
21382142
}
@@ -3704,8 +3708,9 @@ namespace ts {
37043708
return unknownType;
37053709
}
37063710

3707-
let type: Type;
3711+
const typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
37083712
let declaration: JSDocTypedefTag | TypeAliasDeclaration = <JSDocTypedefTag>getDeclarationOfKind(symbol, SyntaxKind.JSDocTypedefTag);
3713+
let type: Type;
37093714
if (declaration) {
37103715
if (declaration.jsDocTypeLiteral) {
37113716
type = getTypeFromTypeNode(declaration.jsDocTypeLiteral);
@@ -3716,12 +3721,12 @@ namespace ts {
37163721
}
37173722
else {
37183723
declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
3719-
type = getTypeFromTypeNode(declaration.type);
3724+
type = getTypeFromTypeNode(declaration.type, symbol, typeParameters);
37203725
}
37213726

37223727
if (popTypeResolution()) {
3723-
links.typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
3724-
if (links.typeParameters) {
3728+
links.typeParameters = typeParameters;
3729+
if (typeParameters) {
37253730
// Initialize the instantiation cache for generic type aliases. The declared type corresponds to
37263731
// an instantiation of the type alias with the type parameters supplied as type arguments.
37273732
links.instantiations = {};
@@ -5226,7 +5231,7 @@ namespace ts {
52265231
// literals and the || and ?: operators). Named types can circularly reference themselves and therefore
52275232
// cannot be deduplicated during their declaration. For example, "type Item = string | (() => Item" is
52285233
// a named type that circularly references itself.
5229-
function getUnionType(types: Type[], noSubtypeReduction?: boolean): Type {
5234+
function getUnionType(types: Type[], noSubtypeReduction?: boolean, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
52305235
if (types.length === 0) {
52315236
return neverType;
52325237
}
@@ -5260,14 +5265,16 @@ namespace ts {
52605265
const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
52615266
type = unionTypes[id] = <UnionType>createObjectType(TypeFlags.Union | propagatedFlags);
52625267
type.types = typeSet;
5268+
type.aliasSymbol = aliasSymbol;
5269+
type.aliasTypeArguments = aliasTypeArguments;
52635270
}
52645271
return type;
52655272
}
52665273

5267-
function getTypeFromUnionTypeNode(node: UnionTypeNode): Type {
5274+
function getTypeFromUnionTypeNode(node: UnionTypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
52685275
const links = getNodeLinks(node);
52695276
if (!links.resolvedType) {
5270-
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*noSubtypeReduction*/ true);
5277+
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*noSubtypeReduction*/ true, aliasSymbol, aliasTypeArguments);
52715278
}
52725279
return links.resolvedType;
52735280
}
@@ -5277,7 +5284,7 @@ namespace ts {
52775284
// a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
52785285
// Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
52795286
// for intersections of types with signatures can be deterministic.
5280-
function getIntersectionType(types: Type[]): Type {
5287+
function getIntersectionType(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
52815288
if (types.length === 0) {
52825289
return emptyObjectType;
52835290
}
@@ -5299,23 +5306,28 @@ namespace ts {
52995306
const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
53005307
type = intersectionTypes[id] = <IntersectionType>createObjectType(TypeFlags.Intersection | propagatedFlags);
53015308
type.types = typeSet;
5309+
type.aliasSymbol = aliasSymbol;
5310+
type.aliasTypeArguments = aliasTypeArguments;
53025311
}
53035312
return type;
53045313
}
53055314

5306-
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode): Type {
5315+
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
53075316
const links = getNodeLinks(node);
53085317
if (!links.resolvedType) {
5309-
links.resolvedType = getIntersectionType(map(node.types, getTypeFromTypeNode));
5318+
links.resolvedType = getIntersectionType(map(node.types, getTypeFromTypeNode), aliasSymbol, aliasTypeArguments);
53105319
}
53115320
return links.resolvedType;
53125321
}
53135322

5314-
function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: Node): Type {
5323+
function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: Node, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
53155324
const links = getNodeLinks(node);
53165325
if (!links.resolvedType) {
53175326
// Deferred resolution of members is handled by resolveObjectTypeMembers
5318-
links.resolvedType = createObjectType(TypeFlags.Anonymous, node.symbol);
5327+
const type = createObjectType(TypeFlags.Anonymous, node.symbol);
5328+
type.aliasSymbol = aliasSymbol;
5329+
type.aliasTypeArguments = aliasTypeArguments;
5330+
links.resolvedType = type;
53195331
}
53205332
return links.resolvedType;
53215333
}
@@ -5378,7 +5390,7 @@ namespace ts {
53785390
return links.resolvedType;
53795391
}
53805392

5381-
function getTypeFromTypeNode(node: TypeNode): Type {
5393+
function getTypeFromTypeNode(node: TypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
53825394
switch (node.kind) {
53835395
case SyntaxKind.AnyKeyword:
53845396
case SyntaxKind.JSDocAllType:
@@ -5421,9 +5433,9 @@ namespace ts {
54215433
return getTypeFromTupleTypeNode(<TupleTypeNode>node);
54225434
case SyntaxKind.UnionType:
54235435
case SyntaxKind.JSDocUnionType:
5424-
return getTypeFromUnionTypeNode(<UnionTypeNode>node);
5436+
return getTypeFromUnionTypeNode(<UnionTypeNode>node, aliasSymbol, aliasTypeArguments);
54255437
case SyntaxKind.IntersectionType:
5426-
return getTypeFromIntersectionTypeNode(<IntersectionTypeNode>node);
5438+
return getTypeFromIntersectionTypeNode(<IntersectionTypeNode>node, aliasSymbol, aliasTypeArguments);
54275439
case SyntaxKind.ParenthesizedType:
54285440
case SyntaxKind.JSDocNullableType:
54295441
case SyntaxKind.JSDocNonNullableType:
@@ -5437,7 +5449,7 @@ namespace ts {
54375449
case SyntaxKind.JSDocTypeLiteral:
54385450
case SyntaxKind.JSDocFunctionType:
54395451
case SyntaxKind.JSDocRecordType:
5440-
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
5452+
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node, aliasSymbol, aliasTypeArguments);
54415453
// This function assumes that an identifier or qualified name is a type expression
54425454
// Callers should first ensure this by calling isTypeNode
54435455
case SyntaxKind.Identifier:
@@ -5490,6 +5502,7 @@ namespace ts {
54905502
count == 2 ? createBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
54915503
createArrayTypeMapper(sources, targets);
54925504
mapper.mappedTypes = sources;
5505+
mapper.targetTypes = targets;
54935506
return mapper;
54945507
}
54955508

@@ -5615,6 +5628,8 @@ namespace ts {
56155628
const result = <AnonymousType>createObjectType(TypeFlags.Anonymous | TypeFlags.Instantiated, type.symbol);
56165629
result.target = type;
56175630
result.mapper = mapper;
5631+
result.aliasSymbol = type.aliasSymbol;
5632+
result.aliasTypeArguments = mapper.targetTypes;
56185633
mapper.instantiations[type.id] = result;
56195634
return result;
56205635
}
@@ -5692,10 +5707,10 @@ namespace ts {
56925707
return createTupleType(instantiateList((<TupleType>type).elementTypes, mapper, instantiateType));
56935708
}
56945709
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
5695-
return getUnionType(instantiateList((<UnionType>type).types, mapper, instantiateType), /*noSubtypeReduction*/ true);
5710+
return getUnionType(instantiateList((<UnionType>type).types, mapper, instantiateType), /*noSubtypeReduction*/ true, type.aliasSymbol, mapper.targetTypes);
56965711
}
56975712
if (type.flags & TypeFlags.Intersection) {
5698-
return getIntersectionType(instantiateList((<IntersectionType>type).types, mapper, instantiateType));
5713+
return getIntersectionType(instantiateList((<IntersectionType>type).types, mapper, instantiateType), type.aliasSymbol, mapper.targetTypes);
56995714
}
57005715
}
57015716
return type;

src/compiler/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2283,6 +2283,8 @@ namespace ts {
22832283
/* @internal */ id: number; // Unique ID
22842284
symbol?: Symbol; // Symbol associated with type (if any)
22852285
pattern?: DestructuringPattern; // Destructuring pattern represented by type (if any)
2286+
aliasSymbol?: Symbol; // Alias associated with type
2287+
aliasTypeArguments?: Type[]; // Alias type arguments (if any)
22862288
}
22872289

22882290
/* @internal */
@@ -2446,6 +2448,7 @@ namespace ts {
24462448
export interface TypeMapper {
24472449
(t: TypeParameter): Type;
24482450
mappedTypes?: Type[]; // Types mapped by this mapper
2451+
targetTypes?: Type[]; // Types substituted for mapped types
24492452
instantiations?: Type[]; // Cache of instantiations created using this type mapper.
24502453
context?: InferenceContext; // The inference context this mapper was created from.
24512454
// Only inference mappers have this set (in createInferenceMapper).

0 commit comments

Comments
 (0)