Skip to content

Commit 2c2d06d

Browse files
committed
Allow new alias to be associated with type alias instantiation
1 parent e388a26 commit 2c2d06d

File tree

2 files changed

+25
-14
lines changed

2 files changed

+25
-14
lines changed

src/compiler/checker.ts

+23-14
Original file line numberDiff line numberDiff line change
@@ -12375,17 +12375,19 @@ namespace ts {
1237512375
return checkNoTypeArguments(node, symbol) ? type : errorType;
1237612376
}
1237712377

12378-
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: readonly Type[] | undefined): Type {
12378+
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: readonly Type[] | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
1237912379
const type = getDeclaredTypeOfSymbol(symbol);
1238012380
if (type === intrinsicMarkerType && intrinsicTypeKinds.has(symbol.escapedName as string) && typeArguments && typeArguments.length === 1) {
1238112381
return getStringMappingType(symbol, typeArguments[0]);
1238212382
}
1238312383
const links = getSymbolLinks(symbol);
1238412384
const typeParameters = links.typeParameters!;
12385-
const id = getTypeListId(typeArguments);
12385+
const id = getTypeListId(typeArguments) + (aliasSymbol ? `@${getSymbolId(aliasSymbol)}` : "");
1238612386
let instantiation = links.instantiations!.get(id);
1238712387
if (!instantiation) {
12388-
links.instantiations!.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration)))));
12388+
links.instantiations!.set(id, instantiation = instantiateType(type,
12389+
createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration))),
12390+
aliasSymbol, aliasTypeArguments));
1238912391
}
1239012392
return instantiation;
1239112393
}
@@ -12411,7 +12413,8 @@ namespace ts {
1241112413
typeParameters.length);
1241212414
return errorType;
1241312415
}
12414-
return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node));
12416+
const aliasSymbol = getAliasSymbolForTypeNode(node);
12417+
return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node), aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
1241512418
}
1241612419
return checkNoTypeArguments(node, symbol) ? type : errorType;
1241712420
}
@@ -15591,9 +15594,9 @@ namespace ts {
1559115594
return getConditionalType(root, mapper);
1559215595
}
1559315596

15594-
function instantiateType(type: Type, mapper: TypeMapper | undefined): Type;
15595-
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined;
15596-
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined {
15597+
function instantiateType(type: Type, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type;
15598+
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type | undefined;
15599+
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type | undefined {
1559715600
if (!(type && mapper && couldContainTypeVariables(type))) {
1559815601
return type;
1559915602
}
@@ -15608,12 +15611,12 @@ namespace ts {
1560815611
totalInstantiationCount++;
1560915612
instantiationCount++;
1561015613
instantiationDepth++;
15611-
const result = instantiateTypeWorker(type, mapper);
15614+
const result = instantiateTypeWorker(type, mapper, aliasSymbol, aliasTypeArguments);
1561215615
instantiationDepth--;
1561315616
return result;
1561415617
}
1561515618

15616-
function instantiateTypeWorker(type: Type, mapper: TypeMapper): Type {
15619+
function instantiateTypeWorker(type: Type, mapper: TypeMapper, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined): Type {
1561715620
const flags = type.flags;
1561815621
if (flags & TypeFlags.TypeParameter) {
1561915622
return getMappedType(type, mapper);
@@ -15634,10 +15637,14 @@ namespace ts {
1563415637
const origin = type.flags & TypeFlags.Union ? (<UnionType>type).origin : undefined;
1563515638
const types = origin && origin.flags & TypeFlags.UnionOrIntersection ? (<UnionOrIntersectionType>origin).types : (<UnionOrIntersectionType>type).types;
1563615639
const newTypes = instantiateTypes(types, mapper);
15637-
return newTypes === types ? type :
15638-
flags & TypeFlags.Intersection || origin && origin.flags & TypeFlags.Intersection ?
15639-
getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) :
15640-
getUnionType(newTypes, UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
15640+
if (newTypes === types && aliasSymbol === type.aliasSymbol) {
15641+
return type;
15642+
}
15643+
const newAliasSymbol = aliasSymbol || type.aliasSymbol;
15644+
const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
15645+
return flags & TypeFlags.Intersection || origin && origin.flags & TypeFlags.Intersection ?
15646+
getIntersectionType(newTypes, newAliasSymbol, newAliasTypeArguments) :
15647+
getUnionType(newTypes, UnionReduction.Literal, newAliasSymbol, newAliasTypeArguments);
1564115648
}
1564215649
if (flags & TypeFlags.Index) {
1564315650
return getIndexType(instantiateType((<IndexType>type).type, mapper));
@@ -15649,7 +15656,9 @@ namespace ts {
1564915656
return getStringMappingType((<StringMappingType>type).symbol, instantiateType((<StringMappingType>type).type, mapper));
1565015657
}
1565115658
if (flags & TypeFlags.IndexedAccess) {
15652-
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper), (<IndexedAccessType>type).noUncheckedIndexedAccessCandidate, /*accessNode*/ undefined, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
15659+
const newAliasSymbol = aliasSymbol || type.aliasSymbol;
15660+
const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
15661+
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper), (<IndexedAccessType>type).noUncheckedIndexedAccessCandidate, /*accessNode*/ undefined, newAliasSymbol, newAliasTypeArguments);
1565315662
}
1565415663
if (flags & TypeFlags.Conditional) {
1565515664
return getConditionalTypeInstantiation(<ConditionalType>type, combineTypeMappers((<ConditionalType>type).mapper, mapper));

src/compiler/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -4745,6 +4745,8 @@ namespace ts {
47454745
typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic)
47464746
outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type
47474747
instantiations?: ESMap<string, Type>; // Instantiations of generic type alias (undefined if non-generic)
4748+
aliasSymbol?: Symbol; // Alias associated with generic type alias instantiation
4749+
aliasTypeArguments?: readonly Type[] // Alias type arguments (if any)
47484750
inferredClassSymbol?: ESMap<SymbolId, TransientSymbol>; // Symbol of an inferred ES5 constructor function
47494751
mapper?: TypeMapper; // Type mapper for instantiation alias
47504752
referenced?: boolean; // True if alias symbol has been referenced as a value that can be emitted

0 commit comments

Comments
 (0)