Bạn có thể chỉ định nhiều ràng buộc loại cho các loại Generics TypeScript không


83

Tôi có một giao diện chung như ví dụ này với một loại ràng buộc duy nhất:

export interface IExample<T extends MyClass> {
    getById(id: number): T;
}

Có thể chỉ định nhiều ràng buộc kiểu thay vì chỉ một?

Câu trả lời:


87

Typecript không cung cấp cú pháp để nhận nhiều thừa kế cho các kiểu chung. Tuy nhiên, bạn có thể đạt được ngữ nghĩa tương tự bằng cách sử dụng các loại Liên minh và loại Giao điểm. Trong trường hợp của bạn, bạn muốn một giao lộ:

interface Example<T extends MyClass & OtherClass> {}

Đối với Liên minh của cả hai loại:

interface Example<T extends MyClass | OtherClass> {}

4
Các kiểu liên minh là một cách tuyệt vời để đạt được điều này vì bạn không cần phải tạo giao diện cho mục đích duy nhất của ràng buộc. Chúng không tồn tại vào năm 2013 - nhưng đây chắc chắn là cách tôi khuyên bạn nên làm ngay bây giờ.
Fenton

5
Câu trả lời này là sai. Các kiểu liên minh không có ngữ nghĩa giống như mở rộng hai kiểu riêng biệt.
AlexG

3
@AlexG Chắc chắn điều này không giống với việc mở rộng hai kiểu mà giống như việc triển khai hai giao diện.
STO

6
Cũng nên nhớ rằng Typecript cũng hỗ trợ các kiểu giao nhau. Vì vậy, <T extends MyInterfaceA & MyInterfaceB>yêu cầu rằng kiểu thực hiện cả hai giao diện.
Tyler Cloutier

2
Theo như tôi hiểu ngữ nghĩa của extends A|Blà mở rộng A HOẶC B cũng như extends A & Bmở rộng cả hai! vì vậy có lẽ bạn nên chỉ định cả hai trong câu trả lời của mình ....
Pipo

34

Một công việc xung quanh việc này sẽ là sử dụng một siêu giao diện (cũng trả lời câu hỏi "tại sao bạn lại cho phép một giao diện kế thừa từ một lớp").

interface ISuperInterface extends MyClass, OtherClass {

}

export interface IExample<T extends ISuperInterface> {
    getById(id: number): T;
}

12
Đây là giải pháp đúng đắn. Mở rộng một giao diện từ hai lớp là loại đáng sợ, mặc dù - nếu cả hai thành viên khai báo tư nhân, giao diện là unfulfillable
Ryan Cavanaugh

1

Tham khảo nhận xét về một giao diện bắt nguồn từ một lớp ... tên là gì?

Tôi tìm thấy điều này trong phần 3.5 của thông số kỹ thuật 0.9.0:

Khai báo giao diện chỉ giới thiệu các kiểu được đặt tên, trong khi khai báo lớp giới thiệu các kiểu được đặt tên và các hàm khởi tạo tạo ra các thể hiện triển khai của các kiểu được đặt tên đó. Các kiểu được đặt tên được giới thiệu bởi khai báo lớp và giao diện chỉ có sự khác biệt nhỏ (các lớp không thể khai báo thành viên tùy chọn và giao diện không thể khai báo thành viên riêng) và trong hầu hết các ngữ cảnh có thể hoán đổi cho nhau. Đặc biệt, các khai báo lớp chỉ có các thành viên công khai giới thiệu các kiểu được đặt tên có chức năng chính xác như những kiểu được tạo bởi khai báo giao diện.


Các thành viên lớp tùy chọn hiện đã được triển khai: github.com/Microsoft/TypeScript/pull/8625
Stefan Rein
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.