microsoft / microsoft/TypeScript
Refinement type inference quirk with implicitly typed `let x`
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Go
- Estrellas
- 111k
- Forks
- 14.4k
- Merge medio
- 1 d 19 h
- PR fusionados (30 d)
- 117
Descripción
🔎 Search Terms
refinement narrow let any
🕗 Version & Regression Information
- This changed between versions 3.9.7 and 4.0.5; the behavior is present in every version from 4.0.5 to 5.3 nightly; I skimmed the whole FAQ document and didn't find anything relevant
⏯ Playground Link
💻 Code
type MyType = { type: 'A' } | { type: 'B' };
function f(arg: MyType) {
let x;
x = arg;
if (x.type === 'A') {
} else if (x.type === 'B') {
} else {
let _: never = x;
}
}
🙁 Actual behavior
error TS2322: Type '{ type: "B"; }' is not assignable to type 'never'.
9 let _: never = x;
~
This is wrong for two reasons:
- In the world of perfect type inference,
xshould be narrowed toneverat this point - Even acknowledging that there could be some practical limitations, the behavior is not consistent.
First conditional successfully eliminates the "A" variant:
But second conditional fails to eliminate the "B" variant:
🙂 Expected behavior
Ideally, this shouldn't be an error at all.
However, given that control-flow-based type inference has its limitations, perhaps some kind of spurious error is inevitable. In that case, it probably should be more like Type 'MyType' is not assignable to type 'never' rather than Type '{ type: "B" }' is not assignable to type 'never'.
Additional information about the issue
Practical impact of this issue is small. There is an easy workaround of adding an explicit type annotation (let x: MyType;).
However, this asymmetry, that the last conditional fails at narrowing when exactly the same conditional before that succeeds, bothers me. I'm reporting this because it could be a symptom of a more general implementation defect.
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 reproduciendo el ejemplo de TypeScript Playground y compara el comportamiento entre las versiones reportadas. Investiga la inferencia y el estrechamiento de tipos basados en el flujo de control para un let con tipo implícito asignado desde MyType; se considera terminado cuando la rama else final se estrecha de forma coherente o produce el diagnóstico acordado sin romper el estrechamiento anterior.
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
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bien especificado
- Aptitud para principiantes
- 35/100