microsoft / microsoft/TypeScript
Refinement type inference quirk with implicitly typed `let x`
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Go
- Star
- 111k
- Fork
- 14.4k
- Merge trung bình
- 1 ngày 19 giờ
- Pull request đã merge (30 ngày)
- 117
Mô tả
🔎 Search Terms
refinement narrow let any
🕗 Version & Regression Information
- This changed between versions 3.9.7 and 4.0.5; the behavior is present in every version from 4.0.5 to 5.3 nightly; I skimmed the whole FAQ document and didn't find anything relevant
⏯ Playground Link
💻 Code
type MyType = { type: 'A' } | { type: 'B' };
function f(arg: MyType) {
let x;
x = arg;
if (x.type === 'A') {
} else if (x.type === 'B') {
} else {
let _: never = x;
}
}
🙁 Actual behavior
error TS2322: Type '{ type: "B"; }' is not assignable to type 'never'.
9 let _: never = x;
~
This is wrong for two reasons:
- In the world of perfect type inference,
xshould be narrowed toneverat this point - Even acknowledging that there could be some practical limitations, the behavior is not consistent.
First conditional successfully eliminates the "A" variant:
But second conditional fails to eliminate the "B" variant:
🙂 Expected behavior
Ideally, this shouldn't be an error at all.
However, given that control-flow-based type inference has its limitations, perhaps some kind of spurious error is inevitable. In that case, it probably should be more like Type 'MyType' is not assignable to type 'never' rather than Type '{ type: "B" }' is not assignable to type 'never'.
Additional information about the issue
Practical impact of this issue is small. There is an easy workaround of adding an explicit type annotation (let x: MyType;).
However, this asymmetry, that the last conditional fails at narrowing when exactly the same conditional before that succeeds, bothers me. I'm reporting this because it could be a symptom of a more general implementation defect.
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 tái hiện ví dụ TypeScript Playground và so sánh hành vi giữa các phiên bản được báo cáo. Điều tra việc suy luận và thu hẹp kiểu dựa trên luồng điều khiển đối với một let được định kiểu ngầm và được gán từ MyType; được xem là hoàn tất khi nhánh else cuối cùng được thu hẹp một cách nhất quán hoặc tạo ra chẩn đoán đã thống nhất mà không làm hỏng việc thu hẹp trướ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ệ
- typescript
- Lĩnh vực
- compilers
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 35/100