首页 > 解决方案 > 扩展接口的接口问题

问题描述

我希望实现 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”

标签: javascripttypescript

解决方案


您是否考虑过使用多态this而不是泛型?你的ComparableandObserver会变成:

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

但是同样,如果您尝试将TestAorTestB视为Observer

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

因此,您可能会决定您实际上不想以equals()这种方式进行约束。


好的,希望有帮助;祝你好运!

Playground 代码链接


推荐阅读