microsoft / microsoft/TypeScript
Regression: recursive conditional+mapped "serialize" type no longer proves `Transform<X>` assignable to `X` on deeply-nested compound types (native-preview; works in tsc)
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.3k
- Merge medio
- 2g 4h
- PR unite (30g)
- 132
Descrizione
Environment
@typescript/native-preview(tsgo)- Last good:
7.0.0-dev.20260421.2 - Broken:
7.0.0-dev.20260618.1…7.0.0-dev.20260622.1(latest) — all fail - Stable
typescript@5.9.3: OK (accepts the code)
So: same source, only the native-preview version changed → a tsgo regression somewhere between 20260421.2 and 20260618.1.
What breaks
A common recursive "serialize" utility type — maps Date | bigint → string recursively through objects and arrays, leaving everything else unchanged (so for a type X containing no Date/bigint, Transform<X> is structurally identical to X):
type Transform<Base, From, To> = {
[K in keyof Base]: Exclude<Base[K], undefined | null> extends never ? Base[K]
: Exclude<Base[K], undefined | null> extends object ? (Exclude<Base[K], undefined|null> extends From ? To | Extract<Base[K], null|undefined> : Transform<Base[K], From, To>)
: Base[K];
};
type TransformJson<T> = Transform<T, Date | bigint, string>;
For a deeply-nested compound type — recursion + arrays + an 8-member discriminated union with a shared base ({base} & ({type:1;…} | {type:2;…} | …)) nested several levels behind arrays — tsgo fails to prove TransformJson<X> assignable to X even when X has no Date/bigint (i.e. when the transform is provably the identity):
error TS2322: Type 'Transform<…, bigint | Date, string>' is not assignable to type '…'.
Type 'Transform<{base} & (…union…), bigint | Date, string>' is not assignable to '{base} & (…union…)'.
tsc proves this assignable; tsgo (new builds) does not.
Diagnosis / things tried (in case it helps narrow the regressed area)
- Adding an up-front "does this subtree contain
From?" guard so the transform returnsBaseverbatim for no-Fromsubtrees → flips the failure intoTS2589"Type instantiation is excessively deep and possibly infinite" across the project, i.e. the extra recursive pass exhausts a depth/instantiation budget. - Bounding the transform's recursion depth (no extra pass) → tsgo then fully expands the type (no TS2589) but still rejects the expanded
{base} & unionintersection-with-union assignment. - So it looks like two compounding limits: (a) a recursion/instantiation budget that's tighter or counted differently than in tsc, and (b) assignability of a mapped-type result back to an intersection-with-union, at depth.
Reproduction note (the awkward part)
I could not reduce this to a small standalone repro: the minimal/standalone versions of the exact pattern (even with the same 8-member intersection-with-union behind arrays) compile clean under both tsgo and tsc. It only reproduces inside a large real project (many hundreds of interacting Transform<…> instantiations across the program), which points at a scale-dependent / cumulative instantiation budget rather than a single-type defect.
Happy to help bisect against the dev-build range, or to share a private reproduction with the team if that's an option.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia eseguendo un bisect delle build native-preview tra 7.0.0-dev.20260421.2 e 7.0.0-dev.20260618.1, confrontando tsgo con tsc sul pattern di progetto segnalato. Esamina il budget di ricorsione o istanziazione e l’assegnabilità dei mapped type profondi; il lavoro è completo quando la regressione è riproducibile, TS2589 viene evitato e l’assegnazione viene ripristinata senza compromettere il comportamento esistente.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- go, typescript
- Ambito
- compilers
- Tipo di issue
- Bug
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Tranquilla
- Chiarezza
- Da chiarire
- Idoneità per principianti
- 28/100