Скажем, у меня есть интерфейс:
interface Comparable<T> {
equals(other:T):boolean
}
Что я реализую в нескольких классах:
class Rectangle implements Comparable<Rectangle> {
equals(other:Rectangle):boolean {
// logic
return true;
}
}
class Circle implements Comparable<Circle> {
equals(other:Circle):boolean {
// logic
return true;
}
}
Почему TypeScript позволяет сравнивать прямоугольник и круг?
let circle:Circle = new Circle();
let rectangle:Rectangle = new Rectangle();
console.log( circle.equals(rectangle) );
Не следует ли мне предупреждать меня, что я предоставил несовместимый тип методу round equals?
Подобно JavaScript, TypeScript использует утиную печать. Поэтому в вашем примере прямоугольник и круг идентичны.
Как только эти классы добавят свои собственные реализации, утиная печать завершится неудачно, а компилятор TypeScript даст вам ошибки.
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;
}
}
Поскольку ваш прямоугольник и круг структурно идентичны, TypeScript рассматривает их как взаимозаменяемые типы (см. "утиная печать" ). Просто заполните круг и прямоугольник, добавив к ним некоторые несовместимые свойства:
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;}
}
И вы увидите сообщение об ошибке. Это, кстати, та же самая причина, по которой вы можете назначить литерал объекта типизированной переменной Circle, если у него есть правильные свойства:
var c: Circle = {rad: 1, equals: () => true}