microsoft / microsoft/TypeScript
Discriminant-specific error message not shown when one constituent of a union has a union-typed discriminant
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ả
TypeScript Version: 3.9.0-dev.20200319
Search Terms: discrimant tagged union assignable
Code
A simplified repro, based on real-world code:
interface A { x: number }
interface B { x: string }
interface U$A { kind: 'A', body: A }
interface U$B { kind: 'B', body: B }
interface U$null { kind: 'C' | 'D', body?: undefined }
type U = U$A | U$B | U$null;
declare function foo(u: U): void;
foo({kind: 'A', body: { x: 42 }}); // OK
foo({kind: 'B', body: { x: 42 }}); // Not OK
Expected behavior:
The second x: 42 gets a squiggle and and the error Type 'number' is not assignable to type 'string'.
Actual behavior:
The whole argument to the second foo call gets a squiggle and the error:
Argument of type '{ kind: "B"; body: { x: number; }; }' is not assignable to parameter of type 'U'. Type '{ kind: "B"; body: { x: number; }; }' is not assignable to type 'U$null'. Types of property 'kind' are incompatible. Type '"B"' is not assignable to type '"C" | "D"'.
I would expect the type of the argument to have been narrowed to U$B by checking the kind property first. As it stands, the developer UX is not ideal especially when the shapes of the types involved get larger and it gets quite hard to figure out which property is wrong (in my real-world case, the union has 250+ members and the error message is incomprehensible).
Notes:
If I change x to y in interface B, the error message comes up OK.
Also, if I comment out the two references to U$null, I get a different (but also acceptable) error.
Related Issues:
None that (at an uneducated guess) seemed to be exactly this one.
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 với bản tái hiện TypeScript Playground được cung cấp và so sánh chẩn đoán được tạo ra cho lệnh gọi foo thứ hai với lỗi cụ thể theo discriminant được mong đợi. Theo dõi luồng của type-checker xử lý các union có discriminant mang kiểu union; được xem là hoàn tất khi lỗi trỏ đến x: 42 và báo rằng number không thể gán cho string mà không làm hồi quy các biến thể đã nêu.
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
- Khá rõ ràng
- Mức phù hợp với người mới
- 32/100