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)
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Go
- Star
- 111k
- Fork
- 14.3k
- Merge trung bình
- 2 ngày 4 giờ
- Pull request đã merge (30 ngày)
- 132
Mô tả
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.
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu bằng cách bisect các bản build native-preview giữa 7.0.0-dev.20260421.2 và 7.0.0-dev.20260618.1, so sánh tsgo với tsc trên mẫu dự án đã được báo cáo. Điều tra ngân sách đệ quy hoặc khởi tạo và khả năng gán của các mapped type lồng sâu; được xem là hoàn tất khi tái hiện được hồi quy, tránh được TS2589 và khôi phục phép gán mà không làm hỏng hành vi hiện có.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- go, typescript
- Lĩnh vực
- compilers
- Loại issue
- Lỗi
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức độ hoạt động
- Ít trao đổi
- Độ rõ ràng
- Cần làm rõ
- Mức phù hợp với người mới
- 28/100