Skip to content

Commit 4bca0a4

Browse files
committed
Guard against recursion in resolveAnonymousTypeMembers
1 parent 70975cd commit 4bca0a4

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

src/compiler/checker.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,6 +2608,12 @@ namespace ts {
26082608
const type = <ObjectType>createType(TypeFlags.Object);
26092609
type.objectFlags = objectFlags;
26102610
type.symbol = symbol!;
2611+
type.members = undefined;
2612+
type.properties = undefined;
2613+
type.callSignatures = undefined;
2614+
type.constructSignatures = undefined;
2615+
type.stringIndexInfo = undefined;
2616+
type.numberIndexInfo = undefined;
26112617
return type;
26122618
}
26132619

@@ -2629,23 +2635,20 @@ namespace ts {
26292635
function getNamedMembers(members: SymbolTable): Symbol[] {
26302636
let result: Symbol[] | undefined;
26312637
members.forEach((symbol, id) => {
2632-
if (!isReservedMemberName(id)) {
2633-
if (!result) result = [];
2634-
if (symbolIsValue(symbol)) {
2635-
result.push(symbol);
2636-
}
2638+
if (!isReservedMemberName(id) && symbolIsValue(symbol)) {
2639+
(result || (result = [])).push(symbol);
26372640
}
26382641
});
26392642
return result || emptyArray;
26402643
}
26412644

26422645
function setStructuredTypeMembers(type: StructuredType, members: SymbolTable, callSignatures: ReadonlyArray<Signature>, constructSignatures: ReadonlyArray<Signature>, stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType {
26432646
(<ResolvedType>type).members = members;
2644-
(<ResolvedType>type).properties = getNamedMembers(members);
2647+
(<ResolvedType>type).properties = members === emptySymbols ? emptyArray : getNamedMembers(members);
26452648
(<ResolvedType>type).callSignatures = callSignatures;
26462649
(<ResolvedType>type).constructSignatures = constructSignatures;
2647-
if (stringIndexInfo) (<ResolvedType>type).stringIndexInfo = stringIndexInfo;
2648-
if (numberIndexInfo) (<ResolvedType>type).numberIndexInfo = numberIndexInfo;
2650+
(<ResolvedType>type).stringIndexInfo = stringIndexInfo;
2651+
(<ResolvedType>type).numberIndexInfo = numberIndexInfo;
26492652
return <ResolvedType>type;
26502653
}
26512654

@@ -5514,7 +5517,7 @@ namespace ts {
55145517
// (otherwise there'd be an error from hasBaseType) - this is fine, but `.members` should be reset
55155518
// as `getIndexedAccessType` via `instantiateType` via `getTypeFromClassOrInterfaceReference` forces a
55165519
// partial instantiation of the members without the base types fully resolved
5517-
(type as Type as ResolvedType).members = undefined!; // TODO: GH#18217
5520+
type.members = undefined; // TODO: GH#18217
55185521
}
55195522
return type.resolvedBaseTypes = [baseType];
55205523
}
@@ -6444,6 +6447,7 @@ namespace ts {
64446447
function resolveAnonymousTypeMembers(type: AnonymousType) {
64456448
const symbol = type.symbol;
64466449
if (type.target) {
6450+
setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined);
64476451
const members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper!, /*mappingThisOnly*/ false);
64486452
const callSignatures = instantiateSignatures(getSignaturesOfType(type.target, SignatureKind.Call), type.mapper!);
64496453
const constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, SignatureKind.Construct), type.mapper!);
@@ -6452,6 +6456,7 @@ namespace ts {
64526456
setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
64536457
}
64546458
else if (symbol.flags & SymbolFlags.TypeLiteral) {
6459+
setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined);
64556460
const members = getMembersOfSymbol(symbol);
64566461
const callSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.Call));
64576462
const constructSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.New));
@@ -6485,7 +6490,7 @@ namespace ts {
64856490
// in the process of resolving (see issue #6072). The temporarily empty signature list
64866491
// will never be observed because a qualified name can't reference signatures.
64876492
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
6488-
(<ResolvedType>type).callSignatures = getSignaturesOfSymbol(symbol);
6493+
type.callSignatures = getSignaturesOfSymbol(symbol);
64896494
}
64906495
// And likewise for construct signatures for classes
64916496
if (symbol.flags & SymbolFlags.Class) {
@@ -6494,7 +6499,7 @@ namespace ts {
64946499
if (!constructSignatures.length) {
64956500
constructSignatures = getDefaultConstructSignatures(classType);
64966501
}
6497-
(<ResolvedType>type).constructSignatures = constructSignatures;
6502+
type.constructSignatures = constructSignatures;
64986503
}
64996504
}
65006505
}
@@ -7674,7 +7679,7 @@ namespace ts {
76747679
// will result in a different declaration kind.
76757680
if (!signature.isolatedSignatureType) {
76767681
const isConstructor = signature.declaration!.kind === SyntaxKind.Constructor || signature.declaration!.kind === SyntaxKind.ConstructSignature; // TODO: GH#18217
7677-
const type = <ResolvedType>createObjectType(ObjectFlags.Anonymous);
7682+
const type = createObjectType(ObjectFlags.Anonymous);
76787683
type.members = emptySymbols;
76797684
type.properties = emptyArray;
76807685
type.callSignatures = !isConstructor ? [signature] : emptyArray;
@@ -10110,7 +10115,7 @@ namespace ts {
1011010115
if (type.flags & TypeFlags.Object) {
1011110116
const resolved = resolveStructuredTypeMembers(<ObjectType>type);
1011210117
if (resolved.constructSignatures.length) {
10113-
const result = <ResolvedType>createObjectType(ObjectFlags.Anonymous, type.symbol);
10118+
const result = createObjectType(ObjectFlags.Anonymous, type.symbol);
1011410119
result.members = resolved.members;
1011510120
result.properties = resolved.properties;
1011610121
result.callSignatures = emptyArray;

src/compiler/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3820,6 +3820,12 @@ namespace ts {
38203820
// Object types (TypeFlags.ObjectType)
38213821
export interface ObjectType extends Type {
38223822
objectFlags: ObjectFlags;
3823+
/* @internal */ members?: SymbolTable; // Properties by name
3824+
/* @internal */ properties?: Symbol[]; // Properties
3825+
/* @internal */ callSignatures?: ReadonlyArray<Signature>; // Call signatures of type
3826+
/* @internal */ constructSignatures?: ReadonlyArray<Signature>; // Construct signatures of type
3827+
/* @internal */ stringIndexInfo?: IndexInfo; // String indexing info
3828+
/* @internal */ numberIndexInfo?: IndexInfo; // Numeric indexing info
38233829
}
38243830

38253831
/** Class and interface types (ObjectFlags.Class and ObjectFlags.Interface). */
@@ -3946,8 +3952,6 @@ namespace ts {
39463952
properties: Symbol[]; // Properties
39473953
callSignatures: ReadonlyArray<Signature>; // Call signatures of type
39483954
constructSignatures: ReadonlyArray<Signature>; // Construct signatures of type
3949-
stringIndexInfo?: IndexInfo; // String indexing info
3950-
numberIndexInfo?: IndexInfo; // Numeric indexing info
39513955
}
39523956

39533957
/* @internal */

0 commit comments

Comments
 (0)