microsoft / microsoft/TypeScript

Spread operator fails to distribute over union when recursive type call is inlined instead of aliased

Aperta
#62,812 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Bug Domain: Conditional Types Help Wanted
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

### 🔎 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.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia dalla riproduzione collegata di TypeScript Playground e confronta i tipi valutati di test2, test3 e test4. Segui la chiamata ricorsiva a CrossProduct e la gestione di spread nel type checker; il lavoro è completo quando test3 viene valutato come la stessa unione completamente distribuita di test2 e test4.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
38/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.