扩展接口的接口的问题

问题描述 投票:0回答:1

我想让实现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'类型中的属性'equals'不可分配给基类型'Observer'中的相同属性。   类型'(item: TestA) => boolean'不可分配给类型'(item: Observer) => boolean'。     参数'item'和'item'的类型不兼容。       在类型'Observer'中没有属性'name',但在类型'TestA'中需要。

但是,TestA实现了Observer接口,为什么它们不兼容?

当然,我可以这样写。

class TestA implements Observer {
    private name = '';

    equals = (item: Observer) => {
        return this.name === item.name
    }

    notify = () => {}
}

但我得到了这样一个错误,而且,这也不完全正确 因为我只想比较这个类的对象。

属性'name'在'观察者'类型上不存在。

怎么做才对?"typecript": "^3.9.2"

javascript typescript
1个回答
2
投票

你是否考虑过使用 多态 this 而不是仿制药? 你的 ComparableObserver 将成为。

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 = () => { }
}

但是,如果你试图处理好这些问题 TestATestB 作为 Observer:

function takeObservers(o1: Observer, o2: Observer) {
    o1.equals(o2);    
}
takeObservers(new TestA()); // error

所以,你可能会决定,你实际上不想限制 equals() 这样。


好的,希望对大家有所帮助;祝大家好运!

游戏场链接代码


0
投票

变化 equals(item: TestA)equals(item:TestB)equals(item : Observer) 在TestA类和TestB类中。

由于Comparable类型被赋予为Observable。

在等价体中,你可以将observable对象投向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 = () => {}
}
© www.soinside.com 2019 - 2024. All rights reserved.