Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Class 为什么可以';";实施;TypeScript 2.4+;中的所有可选接口;?_Class_Typescript - Fatal编程技术网

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
中的错误