javascript - 扩展接口的接口问题
问题描述
我希望实现 Observer 接口的类也实现 Comparable 接口,我该怎么做?
interface Comparable<T> {
equals: (item: T) => boolean;
}
interface Observer extends Comparable<Observer> {
notify: () => void
}
class TestA implements Observer {
private name = '';
equals = (item: TestA) => {
return this.name === item.name
}
notify = () => {}
}
class TestB implements Observer {
private name = '';
equals = (item: TestB) => {
return this.name === item.name
}
notify = () => {}
}
错误:
TS2416:“TestA”类型中的属性“等于”不能分配给基本类型“观察者”中的相同属性。类型 '(item: TestA) => boolean' 不可分配给类型 '(item: Observer) => boolean'。参数“item”和“item”的类型不兼容。“观察者”类型中缺少属性“名称”,但在“TestA”类型中是必需的。
但是,TestA 实现了 Observer 接口,为什么它们不兼容呢?
当然,我可以这样写:
class TestA implements Observer {
private name = '';
equals = (item: Observer) => {
return this.name === item.name
}
notify = () => {}
}
但是后来我得到了这样一个错误,此外,这并不完全正确,因为我只想比较这个类的对象:
“观察者”类型上不存在属性“名称”。
怎么做才对?“打字稿”:“^3.9.2”
解决方案
您是否考虑过使用多态this
而不是泛型?你的Comparable
andObserver
会变成:
interface Comparable {
equals: (item: this) => boolean;
}
interface Observer extends Comparable {
notify: () => void
}
X
这意味着扩展类型的对象Comparable
需要有一个equals()
采用类型值的方法X
。请注意,这意味着它Comparable
在可替换性和继承性方面不像普通类型。一般来说,如果你有,interface B extends A {...}
那么你应该能够在B
任何你需要的地方使用A
:
interface A {
someMethod(x: A): void;
}
interface B extends A {
someOtherMethod(x: B): void;
}
declare const b: B;
const a: A = b; // okay
但这不适用于Comparable
:
declare const o: Observer;
const c: Comparable = o; // error! equals is incompatible
无论如何,这个定义Comparable
将允许您按原样实现:
class TestA implements Observer {
private name = '';
equals = (item: TestA) => {
return this.name === item.name
}
notify = () => { }
}
class TestB implements Observer {
private name = '';
equals = (item: TestB) => {
return this.name === item.name
}
notify = () => { }
}
但是同样,如果您尝试将TestA
orTestB
视为Observer
:
function takeObservers(o1: Observer, o2: Observer) {
o1.equals(o2);
}
takeObservers(new TestA()); // error
因此,您可能会决定您实际上不想以equals()
这种方式进行约束。
好的,希望有帮助;祝你好运!
推荐阅读
- dialogflow-es - Dialogflow中自动扩展实体的组合
- php - 如何计算文件夹中已存在的文件数
- javascript - 我可以将旧版 html/js 脚本添加到 React 中吗
- reactjs - TS:没有类型的 Redux Actions
- java - 在 Java 中获取文本大小(以字节为单位)的最佳方法是什么?
- javascript - ctrl f search only model popup html data
- sql - 根据匹配表对记录进行分类
- z3 - Z3 将数组的默认值设置为零
- ios - 如何在 Swift 中使用反射设置成员变量值?
- facebook - Microsoft 健康机器人服务集成到 Facebook Messenger