microsoft / microsoft/TypeScript
Contextual type doesn't apply to elements of array literal spread into another array literal
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ả
Bug Report
🔎 Search Terms
spread operator, type inference
🕗 Version & Regression Information
- This is the behavior in every version I tried
⏯ Playground Link
Playground link with relevant code
💻 Code
interface Test {
field: 'a' | 'b' | 'c'
}
let arr: Test[] = [
{ field: 'c' },
...[
{ field: 'a' }, // field: string
// ^?
{ field: 'b' }, // field: string
// ^?
]
]
function test(...args: Test[]): void {}
test(
{ field: 'c' },
...[
{ field: 'a' }, // field: string
// ^?
{ field: 'b' }, // field: string
// ^?
]
)
🙁 Actual behavior
The types of objects in the array nested through the spread operator is not inferred to be Test, as such inference begins from scratch, so the type of field in those objects becomes string (and is not detected to be 'a' | 'b' | 'c' which I specified in the interface), and a rather cryptic type error is shown:
Type '{ field: string; }' is not assignable to type 'Test'.
Types of property 'field' are incompatible.
Type 'string' is not assignable to type '"a" | "b" | "c"'.
I have also included an example with using the spread operator in a function call for completeness, it generates basically the same error.
I'm not sure if this is really a bug, but regardless, it is trivial to work around by just forcing compiler's hand a little by doing this:
let arr: Test[] = [
{ field: 'c' },
...[
{ field: 'a' as const },
{ field: 'b' as const },
]
]
Which forces the inferred types of the objects to actually be compatible, or assigning the spread array to a variable with an explicitly defined type:
let nested: Test[] = [
{ field: 'a' },
{ field: 'b' },
]
let arr: Test[] = [
{ field: 'c' },
...nested
]
🙂 Expected behavior
I would expect the type of expr3 in [expr1, expr2, ...expr3] to be inferred to be Iterable<T> or something like that provided that we know that the type of elements of the overall array is T. I believe that in my repro it would make types of nested objects to be inferred correctly as Test.
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 repro Playground được liên kết và xác nhận hành vi của contextual typing đối với các array literal chứa spread, sau đó so sánh với repro Workbench cho trường hợp gọi hàm. Công việc được xem là hoàn tất khi các phần tử object lồng nhau được suy luận là tương thích với Test mà không cần các workaround as const hoặc array được định kiểu riêng như đã nêu, và cả hai ví dụ đều hoạt động như mong đợi.
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ó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- 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
- 25/100