microsoft / microsoft/TypeScript

tsserver hangs indefinitely when inferring return type of class method that passes this to a function with deeply nested conditional return type

Abierto
#63,207 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Bug Domain: check: Type Circularity
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
2 d 4 h
PR fusionados (30 d)
132

Descripción

### 🔎 Search Terms

hang circular

### 🕗 Version & Regression Information

This behavior is present in TypeScript 5 and TypeScript 6 beta.

### ⏯ Playground Link

N/A — requires the remeda package (npm i remeda). Reproduction is a self-contained file below.

### 💻 Code

```ts
import { pick } from "remeda";

export class MyClass {
constructor(public readonly field: number) {}

// [bad] tsserver hangs indefinitely: no explicit return type
getIdentity() {
return pick(this, ["field"]);
}

// [good] works fine: explicit return type breaks the cycle
getIdentityFixed(): Pick {
return pick(this, ["field"]);
}
}
```

### 🙁 Actual behavior

`tsserver` becomes completely unresponsive. The editor (VS Code) loses all language service features (hover types, completions, diagnostics) until tsserver is manually restarted. No error is emitted; tsserver simply loops forever.

The cause is an undetected circular type inference chain. To infer the return type of `getIdentity()`, TypeScript must evaluate `PickFromArray` (remeda's `pick` return type). That involves `IsBoundedRecord` → `IsBounded>`. `KeysOfUnion` uses `UnionToIntersection`, which places `MyClass` in a contravariant function parameter position — forcing eager, non-deferred evaluation of the full structural type of `MyClass`. The full type of `MyClass` includes `getIdentity: () => `, whose inferred return type is what we started trying to compute. Because the cycle passes through ~5 distinct type alias instantiations, TypeScript's cycle-detection heuristics never fire, and the checker loops indefinitely instead of emitting a "circularly references itself" error.

### 🙂 Expected behavior

TypeScript should detect the circular inference and either:

- Emit a "Return type annotation circularly references itself" error (as it does for simpler cycles), or
- Fall back to any with a warning.

Either outcome is acceptable. The checker should never hang.

### Additional information about the issue

Workaround: add an explicit return type annotation to the method. This gives TypeScript the type of `MyClass.getIdentity()` upfront, preventing the cycle from forming.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza instalando remeda y ejecutando la reproducción autocontenida de TypeScript con tsserver. Compara el caso de retorno inferido que se queda bloqueado con la anotación explícita Pick y, después, sigue el tratamiento de la circularidad en torno a la cadena indicada PickFromArray, IsBoundedRecord, IsBounded, KeysOfUnion y UnionToIntersection. Se considera terminado cuando tsserver ya no se queda bloqueado y o bien informa de un error de tipo de retorno circular, o bien recurre a any con una advertencia.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Error
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.