microsoft / microsoft/TypeScript
Spread operator fails to distribute over union when recursive type call is inlined instead of aliased
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
distribution, spread
### 🕗 Version & Regression Information
This is the behavior in every version I tried from version 4.1.5 upwards to 5.9.3 and in nightly v6.0.0-dev.20251127
### ⏯ Playground Link
https://www.typescriptlang.org/play/?ts=5.9.3#code/C4TwDgpgBAwgTgewM5IAqICYFcDGwA8AqgHYCWCxANLAlscBHFBAB4PEZJR0DWxCAd2IBtALoA+KAF4AUFHk06DJq3acow0sQBmjKAC1GCagDozW3UwBKEJMFFyFAfigAKEuWLM2EDlwt6ALIQALYARoyOCs4aweGMpmbwyGiYuAQeFNQ2duIO0dEAXFDEEABujACUUVDFYgDcMgA2EMBQDHYAjMXJKOgI2Hj4xFjxTAA+UHZwWgDm1MJ0GBDaWhAYEvXyAPTbGtNzolCTwiNjDqCQUAAiEGDAABad0rCIfWlDZxETU8AzxPMNEsVmsNpJdvs-odjhovowHC02h1gAAmYquOE-A4A7xqfw6PSZLwudxkCi43zqXj8IRQFzCImJEy3e5PUTFUoVOCVWolcpVLYQ4TYwEio4nTHUTHiyH-QHSmGnUbfahi5qtdq2YAAZnRmJhIopfigASYRLpbnNqkpXGpgmJGkZUDMJl6qQG6WGyr0kxFC2Bq1KYPZfK5PI5-O5Wx2e2FUIBqvjsxlSrGUu9cARGuRABY9RmDUmjepTVBzSSrT5jXbafSnS7XHG5SnpZUQ5yqryO1GoEK-b9m4rJSUMyn+wqJRnE82ZEA
### 💻 Code
```ts
type CrossProduct =
Counter extends [infer Zero, ...infer Rest]
? (Union extends infer Member
? [Member, ...CrossProduct]
: never)
: [];
let test1: CrossProduct; // [string] | [number]
type Depth1 = CrossProduct // [string] | [number]
let test2: (number | string extends infer Union ? (Union extends unknown ? [Union, ...Depth1]: never) : never); // [string, string] | [number, number] | [string, number] | [number, string]
let test3: (number | string extends infer Union ? (Union extends unknown ? [Union, ...CrossProduct]: never) : never); // [string, string] | [number, number]
let test4: (number | string extends infer Union ? (Union extends unknown ? [Union, ...([string] | [number])]: never) : never); // [string, string] | [number, number] | [string, number] | [number, string]
```
### 🙁 Actual behavior
The types of test2 and test4 evaluate to the correct, expected, fully distributed type, while the type of test3 is incompletely distributed (as displayed by IntelliSense in the Playground).
The only difference between test2 and test3 is that in test3 the type that is aliased as Depth1 in test2 is inlined in test3. Thus, both should evaluate to the same type. The type of test2 is correct.
test4 also evaluates correctly. Here the alias is replaced by the literal evaluation result.
### 🙂 Expected behavior
The type of variable test3 should evaluate to
[string, string] | [number, number] | [string, number] | [number, string]
But it evaluates to
[string, string] | [number, number]
### Additional information about the issue
This problem matters since the recursive call in test3 is what I actually need for the construction of a respective recursive type.
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 con la reproducción enlazada de TypeScript Playground y compara los tipos evaluados de test2, test3 y test4. Sigue la llamada recursiva a CrossProduct y el tratamiento de spread en el type checker; el trabajo estará terminado cuando test3 se evalúe como la misma unión completamente distribuida que test2 y test4.
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
- Bastante claro
- Aptitud para principiantes
- 38/100