2016-05-31 25 views
14

Tôi đang sử dụng giao diện trong Typescript để xác định hàm chỉ khả dụng trên một số lớp mở rộng lớp cơ sở. Đây là một phiên bản đơn giản của các mã tôi có cho đến nay:TypeScript - Kiểm tra xem Class có triển khai Giao diện

class Animal { 
} 

interface IWalkingAnimal { 
    walk(): void; 
} 

class Dog extends Animal implements IWalkingAnimal { 
} 

class Cat extends Animal implements IWalkingAnimal { 
} 

class Snake extends Animal { 
} 

private moveAnimal(animal: Animal) { 
    if (animal instanceof Cat || animal instanceof Dog) { 
     animal.walk(); 
    } 
} 

Bây giờ, những rắc rối là tôi sẽ được bổ sung thêm 'đi bộ' động vật nên moveAnimal chức năng sẽ phát triển quá lớn để có thể kiểm soát được. Những gì tôi muốn làm là một cái gì đó như thế này:

private moveAnimal(animal: Animal) { 
    if (animal implements IWalkingAnimal) { 
     animal.walk(); 
    } 
} 

Tuy nhiên kiểm tra 'thực hiện' không hoạt động và tôi không thể tìm thấy tương đương với 'instanceof' khi sử dụng giao diện. Trong Java có vẻ như việc sử dụng 'instanceof' sẽ hoạt động ở đây, nhưng TypeScript sẽ không cho phép điều này.

Có một thứ như vậy tồn tại trong TypeScript hoặc có cách tiếp cận tốt hơn ở đây không? Tôi đang sử dụng TypeScript 1.8.9.

+0

tại sao bạn không có 'IWalkingAnimal' là lớp con của Animal thay vì giao diện? Bằng cách đó bạn sẽ không có vấn đề và nó có ý nghĩa – iberbeu

+0

@iberbeu Điều đó sẽ làm việc cho ví dụ đơn giản này, cho sự linh hoạt tôi muốn IWalkingAnimal là một giao diện để nó không được gắn chặt với Động vật. Câu trả lời của Thilo dưới đây nên làm các thủ thuật. – MarkLunney

+1

Có thể trùng lặp của [Kiểm tra kiểu giao diện với các loại bản ghi] (https://stackoverflow.com/questions/14425568/interface-type-check-with-typescript) –

Trả lời

24

Không giống như các lớp, giao diện chỉ tồn tại trong thời gian biên dịch, chúng không được đưa vào Javascript kết quả, do đó bạn không thể thực hiện kiểm tra instanceof.

Bạn có thể làm IWalkingAnimal một lớp con Thú (và sử dụng instanceof), hoặc bạn có thể kiểm tra xem các đối tượng trong câu hỏi có một phương pháp walk:

if (animal['walk']) {} 

Bạn có thể bọc này trong một user defined type guard (sao cho trình biên dịch có thể thu hẹp loại khi được sử dụng trong câu lệnh if, giống như với instanceof).

/** 
* User Defined Type Guard! 
*/ 
function canWalk(arg: Animal): arg is IWalkingAnimal { 
    return (arg as IWalkingAnimal).walk !== undefined; 
} 


private moveAnimal(animal: Animal) { 
    if (canWalk(animal)) { 
     animal.walk(); // compiler knows it can walk now 
    } 
} 
+2

Tôi đề nghị làm '(arg như IWalkingAnimal) .walk' để nếu bạn quyết định đổi tên phương thức đi bộ thành một thứ khác thì mã trong trình bảo vệ kiểu sẽ thay đổi. –

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