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
Nadie ha tomado este issue todavía.
- 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
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- 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