Javascript 扩展接口的接口的问题
我想让实现Observer接口的类也实现可比较的接口,我该怎么做Javascript 扩展接口的接口的问题,javascript,typescript,Javascript,Typescript,我想让实现Observer接口的类也实现可比较的接口,我该怎么做 interface Comparable<T> { equals: (item: T) => boolean; } interface Observer extends Comparable<Observer> { notify: () => void } class TestA implements Observer { private name = '';
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 = () => {}
}
但是我得到了这样一个错误,而且,这不是完全正确的,因为我只想比较这个类的对象:
类型“Observer”上不存在属性“name”
如何做对?
“类型脚本”:“^3.9.2”将TestA类和TestB类中的等于(项目:TestA)
和等于(项目:TestB)
更改为等于(项目:观察者)
因为可比类型是可观察的
在equals body中,您可以将可观察对象强制转换为TestA,并比较其名称属性,如下所示
在TestA类中
class TestA implements Observer {
private name = '';
equals = (item: Observer) => {
if(item instanceof TestA){
return this.name === (item as TestA).name
}
return false
}
notify = () => {}
}
将TestA类和TestB类中的等于(项目:TestA)
和等于(项目:TestB)
更改为等于(项目:观察者)
因为可比类型是可观察的
在equals body中,您可以将可观察对象强制转换为TestA,并比较其名称属性,如下所示
在TestA类中
class TestA implements Observer {
private name = '';
equals = (item: Observer) => {
if(item instanceof TestA){
return this.name === (item as TestA).name
}
return false
}
notify = () => {}
}
你考虑过使用泛型而不是泛型吗?您的可比
和观察者
将成为:
interface Comparable {
equals: (item: this) => boolean;
}
interface Observer extends Comparable {
notify: () => void
}
这意味着扩展Comparable
的X
类型的对象需要有一个equals()
方法,该方法采用X
类型的值。请注意,这意味着Comparable
在可替换性和继承性方面与普通类型不同。通常,如果您有接口B扩展了{…}
,那么您应该能够在需要A
的任何地方使用B
:
interface A {
someMethod(x: A): void;
}
interface B extends A {
someOtherMethod(x: B): void;
}
declare const b: B;
const a: A = b; // okay
但这不适用于可比较的:
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
或TestB
视为观察者,您将再次遇到问题:
function takeObservers(o1: Observer, o2: Observer) {
o1.equals(o2);
}
takeObservers(new TestA()); // error
因此,您可能决定实际上不希望以这种方式约束equals()
好吧,希望这会有帮助;祝你好运
您是否考虑过使用泛型而不是泛型?您的可比
和观察者
将成为:
interface Comparable {
equals: (item: this) => boolean;
}
interface Observer extends Comparable {
notify: () => void
}
这意味着扩展Comparable
的X
类型的对象需要有一个equals()
方法,该方法采用X
类型的值。请注意,这意味着Comparable
在可替换性和继承性方面与普通类型不同。通常,如果您有接口B扩展了{…}
,那么您应该能够在需要A
的任何地方使用B
:
interface A {
someMethod(x: A): void;
}
interface B extends A {
someOtherMethod(x: B): void;
}
declare const b: B;
const a: A = b; // okay
但这不适用于可比较的:
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
或TestB
视为观察者,您将再次遇到问题:
function takeObservers(o1: Observer, o2: Observer) {
o1.equals(o2);
}
takeObservers(new TestA()); // error
因此,您可能决定实际上不希望以这种方式约束equals()
好吧,希望这会有帮助;祝你好运
这不合适,因为我可以这样做:new TestA().equals(new TestB)并且我不会从TypeScript中得到错误。您能解释什么不合适吗?它会合适,因为当您执行new TestA().equals(new TestB)时,它将返回false我的意思是TS不会报告类型中的错误,但我想始终确保我将TestA与TestA和TestB与TestBin进行比较。在这种情况下,您必须更改接口和类的设计。对于当前的设计,您无法实现这一点,因为我可以这样做:new TestA().equals(new TestB)并且我不会从类型脚本中得到错误。您可以解释什么不适合吗?它适合,因为当您执行new TestA().equals(new TestB)时,它将返回false我的意思是TS不会报告类型中的错误,但我想始终确保我将TestA与TestA和TestB与TestBin进行比较。在这种情况下,您必须更改接口和类的设计。以目前的设计,你无法实现多态这-这是我所需要的,非常感谢!多态这-这是我需要的,非常感谢!