9

Hãy nói rằng tôi có một giao diện:Loại kiểm tra và Generics

interface Comparable<T> { 
    equals(other:T):boolean 
} 

Mà sau đó tôi thực hiện ở một số lớp học:

class Rectangle implements Comparable<Rectangle> { 

    equals(other:Rectangle):boolean { 
     // logic 
     return true; 
    } 

} 

class Circle implements Comparable<Circle> { 

    equals(other:Circle):boolean { 
     // logic 
     return true; 
    } 

} 

Tại sao nguyên cảo cho phép so sánh hình chữ nhật và hình tròn?

let circle:Circle = new Circle(); 
let rectangle:Rectangle = new Rectangle(); 
console.log(circle.equals(rectangle)); 

không nên nó cảnh báo với tôi rằng tôi cung cấp loại không phù hợp với vòng tròn của bằng phương pháp?

Trả lời

9

Giống như JavaScript, TypeScript sử dụng tính năng nhập vịt. Vì vậy, trong hình chữ nhật và hình tròn ví dụ của bạn giống hệt nhau.

Sau khi các lớp này thêm triển khai của riêng chúng, việc nhập vịt sẽ thất bại và trình biên dịch TypeScript sẽ cung cấp cho bạn lỗi.

class Rectangle implements Comparable<Rectangle> { 

    width: number; 
    height: number; 

    equals(other:Rectangle): boolean { 
     // logic 
     return true; 
    } 

} 

class Circle implements Comparable<Circle> { 

    diameter: number; 

    equals(other:Circle): boolean { 
     // logic 
     return true; 
    } 

} 
6

Vì hình chữ nhật và hình tròn của bạn có cấu trúc giống nhau, TypeScript coi chúng là loại có thể thay thế được (xem "nhập vịt"). Chỉ cần tô ra vòng tròn và hình chữ nhật của bạn bằng cách thêm một số thuộc tính không tương thích lẫn nhau cho chúng:

class Rectangle implements Comparable<Rectangle> { 
    x: number; 
    equals(other:Rectangle):boolean {return true;} 
} 
class Circle implements Comparable<Circle> { 
    rad: number; 
    equals(other:Circle):boolean {return true;} 
} 

Và bạn sẽ thấy lỗi hiển thị. Điều này, một cách ngẫu nhiên, cùng một lý do khiến bạn có thể gán một đối tượng theo nghĩa đen cho một vòng tròn được đánh máy var, miễn là nó có thuộc tính phù hợp:

var c: Circle = {rad: 1, equals:() => true}