mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Ensure instantiation expressions have symbols, preventing crash in signature relations (#56064)
This commit is contained in:
+18
-15
@@ -6838,6 +6838,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const typeId = type.id;
|
||||
const symbol = type.symbol;
|
||||
if (symbol) {
|
||||
const isInstantiationExpressionType = !!(getObjectFlags(type) & ObjectFlags.InstantiationExpressionType);
|
||||
if (isInstantiationExpressionType) {
|
||||
const instantiationExpressionType = type as InstantiationExpressionType;
|
||||
const existing = instantiationExpressionType.node;
|
||||
if (isTypeQueryNode(existing) && getTypeFromTypeNode(existing) === type) {
|
||||
const typeNode = serializeExistingTypeNode(context, existing);
|
||||
if (typeNode) {
|
||||
return typeNode;
|
||||
}
|
||||
}
|
||||
if (context.visitedTypes?.has(typeId)) {
|
||||
return createElidedInformationPlaceholder(context);
|
||||
}
|
||||
return visitAndTransformType(type, createTypeNodeFromObjectType);
|
||||
}
|
||||
const isInstanceType = isClassInstanceSide(type) ? SymbolFlags.Type : SymbolFlags.Value;
|
||||
if (isJSConstructor(symbol.valueDeclaration)) {
|
||||
// Instance and static types share the same symbol; only add 'typeof' for the static side.
|
||||
@@ -6869,20 +6884,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const isInstantiationExpressionType = !!(getObjectFlags(type) & ObjectFlags.InstantiationExpressionType);
|
||||
if (isInstantiationExpressionType) {
|
||||
const instantiationExpressionType = type as InstantiationExpressionType;
|
||||
if (isTypeQueryNode(instantiationExpressionType.node)) {
|
||||
const typeNode = serializeExistingTypeNode(context, instantiationExpressionType.node);
|
||||
if (typeNode) {
|
||||
return typeNode;
|
||||
}
|
||||
}
|
||||
if (context.visitedTypes?.has(typeId)) {
|
||||
return createElidedInformationPlaceholder(context);
|
||||
}
|
||||
return visitAndTransformType(type, createTypeNodeFromObjectType);
|
||||
}
|
||||
// Anonymous types without a symbol are never circular.
|
||||
return createTypeNodeFromObjectType(type);
|
||||
}
|
||||
@@ -19542,6 +19543,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): AnonymousType {
|
||||
Debug.assert(type.symbol, "anonymous type must have symbol to be instantiated");
|
||||
const result = createObjectType(type.objectFlags & ~(ObjectFlags.CouldContainTypeVariablesComputed | ObjectFlags.CouldContainTypeVariables) | ObjectFlags.Instantiated, type.symbol) as AnonymousType;
|
||||
if (type.objectFlags & ObjectFlags.Mapped) {
|
||||
(result as MappedType).declaration = (type as MappedType).declaration;
|
||||
@@ -23074,6 +23076,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// method). Simply do a pairwise comparison of the signatures in the two signature lists instead
|
||||
// of the much more expensive N * M comparison matrix we explore below. We erase type parameters
|
||||
// as they are known to always be the same.
|
||||
Debug.assertEqual(sourceSignatures.length, targetSignatures.length);
|
||||
for (let i = 0; i < targetSignatures.length; i++) {
|
||||
const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors, intersectionState, incompatibleReporter(sourceSignatures[i], targetSignatures[i]));
|
||||
if (!related) {
|
||||
@@ -35677,7 +35680,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
hasSignatures ||= resolved.callSignatures.length !== 0 || resolved.constructSignatures.length !== 0;
|
||||
hasApplicableSignature ||= callSignatures.length !== 0 || constructSignatures.length !== 0;
|
||||
if (callSignatures !== resolved.callSignatures || constructSignatures !== resolved.constructSignatures) {
|
||||
const result = createAnonymousType(/*symbol*/ undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos) as ResolvedType & InstantiationExpressionType;
|
||||
const result = createAnonymousType(createSymbol(SymbolFlags.None, InternalSymbolName.InstantiationExpression), resolved.members, callSignatures, constructSignatures, resolved.indexInfos) as ResolvedType & InstantiationExpressionType;
|
||||
result.objectFlags |= ObjectFlags.InstantiationExpressionType;
|
||||
result.node = node;
|
||||
return result;
|
||||
|
||||
@@ -5955,6 +5955,7 @@ export const enum InternalSymbolName {
|
||||
ExportEquals = "export=", // Export assignment symbol
|
||||
Default = "default", // Default export symbol (technically not wholly internal, but included here for usability)
|
||||
This = "this",
|
||||
InstantiationExpression = "__instantiationExpression", // Instantiation expressions
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user