2015-02-02 22 views
7

Tôi có một lớp Typecript bao gồm một generic cần mở rộng một lớp khác và thực hiện một giao diện. Dưới đây là ví dụGenerics Typescript mở rộng lớp và giao diện

interface IHasImage { 
    imageUrl():string; 
} 
class Model { 
} 
class View<T extends Model & IHasImage> { 
} 

Đây là loại cú pháp tôi đã thấy ở nơi khác nhưng có cách nào để làm điều này trong Typecript?

chỉnh sửa: Hãy thử dán sau vào sân chơi: http://www.typescriptlang.org/Playground

...[removed edit 1 code] 

chỉnh sửa 2: trả lời và lý luận

(Tôi xin lỗi, ví dụ đầu tiên đã có một vài sai sót!) Tôi đã đánh dấu câu trả lời chính xác bên dưới, mặc dù có thể cần một vài gợi ý như được nêu trong vấn đề github này (https://github.com/Microsoft/TypeScript/issues/1885)

Với mã sau bạn có thể thấy phương pháp luận hoạt động.

playground screenshot

Chỉ có điều khác để nói là cố gắng để implement giao diện từ một lớp học mà không mở rộng các lớp cơ sở cũng thất bại. Tuy nhiên vì kiểm tra Typecript là dựa trên cấu trúc của đối tượng, nó sẽ thành công nếu bạn thêm thuộc tính name vào lớp một cách thủ công.

enter image description here

Đây cũng là lý do tại sao nó thành công với ModelCorrectextends nhưng không implements.

+0

tôi nghĩ rằng có lỗi trong ví dụ. điều này trong constructor không phải là giá trị kiểu generic.Lớp nên có một mô hình: T tài sản hoặc constructur có thể chấp nhận một giá trị: T đối số – Martijn

Trả lời

3

Có vẻ như đây là cách duy nhất để làm điều đó mà tôi có thể tìm thấy. Không hoàn toàn sạch sẽ nhưng nó làm điều đúng.

interface IHasImage extends Model{ 
    imageUrl():string; 
} 

class Model { 
} 

class View<T extends IHasImage> { 
} 

Đây là một ảnh chụp màn hình từ sân chơi xác minh rằng nó hoạt động:

playground

Edit: Thêm workaround đúng.

+0

Tôi đã cố gắng đó, và nó không biên dịch nhưng tôi không nghĩ rằng nó làm những gì tôi đang tìm kiếm vì khi tôi cố gắng làm 'this.model .imageUrl() 'nó than phiền T không có hàm' imageUrl' –

+0

Chỉnh sửa câu trả lời của tôi, với một giải pháp thay thế. – dignifiedquire

+0

Tôi sẽ cho rằng một đi, tôi nghĩ rằng tôi đã cố gắng nhưng có thể đã không thực hiện –

14

nguyên cảo không phải là quá hạn chế như Java hay C#, do đó bạn có thể làm những việc như thế:

interface IHasImage { 
    imageUrl():string; 
} 

class Model { 
} 

// use the Model class like an interface 
interface IHasImageModel extends IHasImage, Model{ 
} 

class View<T extends IHasImageModel> { 
    constructor(arg :T){ 
     arg.imageUrl(); 
    } 
} 

Edit: Trong nguyên cảo 1.6 bạn có thể sử dụng các loại Intersection:

interface IHasImage { 
    imageUrl():string; 
} 

class Model { 
} 

class View<T extends IHasImage & Model> { 
    constructor(arg :T){ 
     arg.imageUrl(); 
    } 
} 
+1

'class View 'thực sự có nghĩa là gì? – SuperUberDuper

+1

@SuperUberDuper Đây là câu hỏi cho mục nhập stackoverflow mới. Nói tóm lại, đó là cách phân loại cho một lớp chung https://www.typescriptlang.org/docs/handbook/generics.html#generic-classes Bạn có thể sử dụng lớp này với tất cả các kiểu đáp ứng các yêu cầu \t "mở rộng IHasImage & Model " – Magu

+0

great thx !!!!!!!! – SuperUberDuper

1

Thiếu trong ví dụ là những gì T sẽ là:

Trong ví dụ dưới đây tôi đã thêm một triển khai cho T, có thể được sử dụng làm ràng buộc chung.

interface IHasImage { 
    imageUrl():string; 
} 

class Model { 
} 

class ModelWithImage extends Model implements IHasImage { 

    imageUrl():string 
    { 
    return "http://thepetwiki.com/images/thumb/Kitten.jpg/400px-Kitten.jpg"; 
    } 
} 


class View<T extends ModelWithImage> 
{ 
    value:T; 

    constructor(arg:T) 
    { 
     this.value=arg; 
    }  
} 
+0

mô hình mở rộng quá cụ thể ở đây không may là nhiều loại mô hình có thể có cùng chức năng 'IHasImage' –

Các vấn đề liên quan