У меня была игра с TypeScript и интерфейсами. У меня есть следующий код:Интерфейсы и реализация интерфейса TypeScript
interface Control {
name: string;
onSelect():string;
}
class Button {
name:string="button";
onSelect = function() {
return "hello";
}
}
var a:Button = new Button();
var b:Control = {"name": "arbitrary", "onSelect":() => { return "ahoy!"; }};
var trigger = function(c:Button) {
console.log(c.name, "says", c.onSelect());
}
trigger(a);
trigger(b);
Которая компилируется и работает без жалобы. Может ли кто-нибудь объяснить, почему моя функция trigger
принимает b
, хотя она ожидает получить тип Button
и b
имеет тип Control
.
Даже если Button
были явно реализовать Control
, я прошу для Button
а не Control
. Для всех назначенных целей Button
может содержать дополнительные элементы.
Является ли TypeScript выводом реализации только потому, что они структурно одинаковы? Разрешено ли передавать интерфейс, где ожидается реализация класса? (Она не должна быть наоборот?)
Если 'Button' имеет частный член, то только его (или классы, которые простираются от него) будут считаться совместимыми. Вы можете подумать о добавлении «фиктивного» частного члена, если это желаемое поведение. –
Я вижу. Я подумывал о добавлении фиктивного члена. На ваш взгляд, строгий тип принуждает что-то ненужное? Это противоречит принципам TS? –
Я бы сказал, что он редко продуктивен, но всегда есть исключения. Это скорее дизайнерский запах, если «триггер» на самом деле зависит от аспектов «Button», отличных от тех, которые он использует, в конце концов. –