Skip to content

Commit e27fb06

Browse files
authored
Fix crash in recursive declared type resolution (microsoft#23950)
When one type has a type parameter with a default
1 parent b31968a commit e27fb06

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

src/compiler/checker.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -5656,6 +5656,10 @@ namespace ts {
56565656
const symbol = type.symbol;
56575657
const members = getMembersOfSymbol(symbol);
56585658
(<InterfaceTypeWithDeclaredMembers>type).declaredProperties = getNamedMembers(members);
5659+
// Start with signatures at empty array in case of recursive types
5660+
(<InterfaceTypeWithDeclaredMembers>type).declaredCallSignatures = emptyArray;
5661+
(<InterfaceTypeWithDeclaredMembers>type).declaredConstructSignatures = emptyArray;
5662+
56595663
(<InterfaceTypeWithDeclaredMembers>type).declaredCallSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.Call));
56605664
(<InterfaceTypeWithDeclaredMembers>type).declaredConstructSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.New));
56615665
(<InterfaceTypeWithDeclaredMembers>type).declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.String);
@@ -7048,7 +7052,7 @@ namespace ts {
70487052
for (let i = numTypeArguments; i < numTypeParameters; i++) {
70497053
const mapper = createTypeMapper(typeParameters, typeArguments);
70507054
let defaultType = getDefaultFromTypeParameter(typeParameters[i]);
7051-
if (defaultType && isTypeIdenticalTo(defaultType, emptyObjectType) && isJavaScriptImplicitAny) {
7055+
if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) {
70527056
defaultType = anyType;
70537057
}
70547058
typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScriptImplicitAny);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
=== tests/cases/compiler/types.ts ===
2+
// #23025
3+
export interface F {
4+
>F : Symbol(F, Decl(types.ts, 0, 0))
5+
6+
(): E;
7+
>E : Symbol(E, Decl(other.js, 0, 4))
8+
}
9+
export interface D<T extends F = F> {}
10+
>D : Symbol(D, Decl(types.ts, 3, 1))
11+
>T : Symbol(T, Decl(types.ts, 4, 19))
12+
>F : Symbol(F, Decl(types.ts, 0, 0))
13+
>F : Symbol(F, Decl(types.ts, 0, 0))
14+
15+
=== tests/cases/compiler/other.js ===
16+
/** @typedef {import("./types").D} E */
17+
No type information for this code.
18+
No type information for this code.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
=== tests/cases/compiler/types.ts ===
2+
// #23025
3+
export interface F {
4+
>F : F
5+
6+
(): E;
7+
>E : D<any>
8+
}
9+
export interface D<T extends F = F> {}
10+
>D : D<T>
11+
>T : T
12+
>F : F
13+
>F : F
14+
15+
=== tests/cases/compiler/other.js ===
16+
/** @typedef {import("./types").D} E */
17+
No type information for this code.
18+
No type information for this code.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// #23025
2+
// @noEmit: true
3+
// @allowJs: true
4+
// @checkJs: true
5+
// @Filename: types.ts
6+
export interface F {
7+
(): E;
8+
}
9+
export interface D<T extends F = F> {}
10+
11+
// @Filename: other.js
12+
/** @typedef {import("./types").D} E */

0 commit comments

Comments
 (0)