8000 Support re-aliasing of type alias instantiations by ahejlsberg · Pull Request #42284 · microsoft/TypeScript · GitHub
[go: up one dir, main page]

Skip to content

Support re-aliasing of type alias instantiations #42284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 11, 2021
Merged
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
Next Next commit
New aliases for type alias instantiations
  • Loading branch information
ahejlsberg committed Jan 9, 2021
commit a4a47dbb0a4bdde77a47ce949566d53336029bdc
36 changes: 23 additions & 13 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12443,17 +12443,20 @@ namespace ts {
return checkNoTypeArguments(node, symbol) ? type : errorType;
}

function getTypeAliasInstantiation(symbol: Symbol, typeArguments: readonly Type[] | undefined): Type {
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: readonly Type[] | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
const type = getDeclaredTypeOfSymbol(symbol);
if (type === intrinsicMarkerType && intrinsicTypeKinds.has(symbol.escapedName as string) && typeArguments && typeArguments.length === 1) {
return getStringMappingType(symbol, typeArguments[0]);
}
const links = getSymbolLinks(symbol);
const typeParameters = links.typeParameters!;
const id = getTypeListId(typeArguments);
const id = getTypeListId(typeArguments) + (aliasSymbol ? `@${getSymbolId(aliasSymbol)}` : "");
let instantiation = links.instantiations!.get(id);
if (!instantiation) {
links.instantiations!.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration)))));
links.instantiations!.set(id, instantiation = instantiateType(type,
createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration))),
aliasSymbol, aliasTypeArguments));
}
return instantiation;
}
Expand All @@ -12479,7 +12482,8 @@ namespace ts {
typeParameters.length);
return errorType;
}
return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node));
const aliasSymbol = getAliasSymbolForTypeNode(node);
return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node), aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
}
return checkNoTypeArguments(node, symbol) ? type : errorType;
}
Expand Down Expand Up @@ -15658,9 +15662,9 @@ namespace ts {
return getConditionalType(root, mapper);
}

function instantiateType(type: Type, mapper: TypeMapper | undefined): Type;
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined;
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined {
function instantiateType(type: Type, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type;
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type | undefined;
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type | undefined {
if (!(type && mapper && couldContainTypeVariables(type))) {
return type;
}
Expand All @@ -15675,12 +15679,12 @@ namespace ts {
totalInstantiationCount++;
instantiationCount++;
instantiationDepth++;
const result = instantiateTypeWorker(type, mapper);
const result = instantiateTypeWorker(type, mapper, aliasSymbol, aliasTypeArguments);
instantiationDepth--;
return result;
}

function instantiateTypeWorker(type: Type, mapper: TypeMapper): Type {
function instantiateTypeWorker(type: Type, mapper: TypeMapper, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined): Type {
const flags = type.flags;
if (flags & TypeFlags.TypeParameter) {
return getMappedType(type, mapper);
Expand All @@ -15701,10 +15705,14 @@ namespace ts {
const origin = type.flags & TypeFlags.Union ? (<UnionType>type).origin : undefined;
const types = origin && origin.flags & TypeFlags.UnionOrIntersection ? (<UnionOrIntersectionType>origin).types : (<UnionOrIntersectionType>type).types;
const newTypes = instantiateTypes(types, mapper);
return newTypes === types ? type :
flags & TypeFlags.Intersection || origin && origin.flags & TypeFlags.Intersection ?
getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) :
getUnionType(newTypes, UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
if (newTypes === types && aliasSymbol === type.aliasSymbol) {
return type;
}
const newAliasSymbol = aliasSymbol || type.aliasSymbol;
const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
return flags & TypeFlags.Intersection || origin && origin.flags & TypeFlags.Intersection ?
getIntersectionType(newTypes, newAliasSymbol, newAliasTypeArguments) :
getUnionType(newTypes, UnionReduction.Literal, newAliasSymbol, newAliasTypeArguments);
}
if (flags & TypeFlags.Index) {
return getIndexType(instantiateType((<IndexType>type).type, mapper));
Expand All @@ -15716,7 +15724,9 @@ namespace ts {
return getStringMappingType((<StringMappingType>type).symbol, instantiateType((<StringMappingType>type).type, mapper));
}
if (flags & TypeFlags.IndexedAccess) {
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper), (<IndexedAccessType>type).noUncheckedIndexedAccessCandidate, /*accessNode*/ undefined, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
const newAliasSymbol = aliasSymbol || type.aliasSymbol;
const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper), (<IndexedAccessType>type).noUncheckedIndexedAccessCandidate, /*accessNode*/ undefined, newAliasSymbol, newAliasTypeArguments);
}
if (flags & TypeFlags.Conditional) {
return getConditionalTypeInstantiation(<ConditionalType>type, combineTypeMappers((<ConditionalType>type).mapper, mapper));
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4745,6 +4745,8 @@ namespace ts {
typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic)
outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type
instantiations?: ESMap<string, Type>; // Instantiations of generic type alias (undefined if non-generic)
aliasSymbol?: Symbol; // Alias associated with generic type alias instantiation
aliasTypeArguments?: readonly Type[] // Alias type arguments (if any)
inferredClassSymbol?: ESMap<SymbolId, TransientSymbol>; // Symbol of an inferred ES5 constructor function
mapper?: TypeMapper; // Type mapper for instantiation alias
referenced?: boolean; // True if alias symbol has been referenced as a value that can be emitted
Expand Down
0