Class 为什么可以';";实施;TypeScript 2.4+;中的所有可选接口;?
我写了一些代码:Class 为什么可以';";实施;TypeScript 2.4+;中的所有可选接口;?,class,typescript,Class,Typescript,我写了一些代码: interface IEventListener { onBefore?(name: string): void; onAfter?(name: string): void; } class BaseListener implements IEventListener { stuff() { } } 这里的目的是,有人可以从BaseListener派生,并在onBefore/onAfter方法上获得正确的类型检查: class Deriv
interface IEventListener {
onBefore?(name: string): void;
onAfter?(name: string): void;
}
class BaseListener implements IEventListener {
stuff() {
}
}
这里的目的是,有人可以从BaseListener
派生,并在onBefore
/onAfter
方法上获得正确的类型检查:
class DerivedListener extends BaseListener {
// Should be an error (name is string, not number)
onBefore(name: number) {
}
}
但是,DerivedListener
中没有错误。相反,我在BaseListener
中遇到了一个错误:
类型“BaseListener”与类型“IEventListener”没有共同的属性
发生了什么?TypeScript中的
implements
子句只做了一件事:它确保声明类可分配给实现的接口。换句话说,当您编写类BaseListener实现IEventListener
时,TypeScript会检查此代码是否合法:
var x: BaseListener = ...;
var y: IEventListener = x; // OK?
因此,当您编写类BaseListener实现IEventListener
时,您可能想要做的是将IEventListener
的可选属性“复制”到类声明中
相反,什么也没发生
TypeScript 2.4更改了所有可选类型的工作方式。以前,任何没有冲突类型属性的类型都可以分配给所有可选类型。这导致各种恶作剧被允许:
interface HttpOptions {
method?: string;
url?: string;
host?: string;
port?: number;
}
interface Point {
x: number;
y: number;
}
const pt: Point = { x: 2, y: 4 };
const opts: HttpOptions = pt; // No error, wat?
从2.4开始的新行为是,全可选类型要求源类型中至少有一个匹配属性,才能将该类型视为兼容。这捕获了上面的错误,并正确地指出您试图实现接口而实际上什么也不做
相反,您应该使用声明合并将接口成员“复制”到类中。这与编写与类同名(和相同类型参数,如果有)的接口声明一样简单:
interface IEventListener {
onBefore?(name: string): void;
onAfter?(name: string): void;
}
class BaseListener {
stuff() {
}
}
interface BaseListener extends IEventListener { }
这将导致IEventListener
的属性也位于BaseListener
中,并在原始帖子中正确标记DerivedListener
中的错误