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)

Aperta
#63,845 9 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Needs More Info
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.17.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 | bigintstring 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 returns Base verbatim for no-From subtrees → flips the failure into TS2589 "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} & union intersection-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

  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 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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.