我正在尝试使用与以下示例相同名称的接口和类在我的代码中强制执行事件定义:
export declare interface ClientEvents {
on(event: "event_name", data: (data: string) => void) : this;
emit(event: "event_name", data: string) : boolean;
}
export class ClientEvents extends EventEmitter {}
对于IDE的完成,它本身可以很好地工作,并确保事件对象仅广播那些事件。
当我尝试扩展此接口时出现问题,如下所示:
export declare interface SpecificClientEvents extends ClientEvents {
on(event: "child_event_name", data: (data: string) => void) : this;
emit(event: "child_event_name", data: string) : boolean;
}
export class SpecificClientEvents extends ClientEvents {}
我收到以下错误:
接口的TS2430: Interface 'SpecificClientEvents' incorrectly extends interface 'ClientEvents'.
TS2415: Class 'SpecificClientEvents' incorrectly extends base class 'ClientEvents'.
for the class
我还尝试按照下面的示例将类和接口分成单独的定义:
export interface ClientEventDefinitions {
on(event: "event_name", data: (data: string) => void) : this;
emit(event: "event_name", data: string) : boolean;
}
export class ClientEvents extends EventEmitter implements ClientEventDefinitions {}
export interface SpecificClientEventDefinitions {
on(event: "child_event_name", data: (data: string) => void) : this;
emit(event: "child_event_name", data: string) : boolean;
}
export class SpecificClientEvents extends ClientEvents implements SpecificClientEventDefinitions {}
这可以编译,但是我的IDE不能像类和接口具有相同名称时一样检测事件名称。 IDE可能有问题吗?这不适用于父类和子类。
使用第二个示例,我也可以无任何错误地执行new SpecificClientEvents().emit("an event that isn't defined");
。
编辑:
如果我将方法从父接口手动添加到子接口,则可以正常工作。但是,如果我需要手动添加方法,首先扩展父级有什么意义?
您的第一个示例具有预期的行为。为了简化起见,以下是简化版本:
interface A {
prop: 'String literal type';
}
interface B extends A {
prop: 'Another string literal type';
}
这将为您显示一条错误消息:Type '"Another string literal type"' is not assignable to type '"String literal type"'
我还能够执行新的SpecificClientEvents()。emit(“事件未定义”);使用第二个示例不会出现任何错误。
这似乎是因为implements
没有强制执行SpecificClientEventDefinitions
中的字符串文字类型,而是使用了EventEmitter
(string | Symbol
)中的类型。
这是我认为可以解决您问题的另一种方法:
export class SpecificClientEvents extends EventEmitter {
on(event: 'child_event_name', data: (data: string) => void): this {
return super.on(event, data);
}
emit(event: 'child_event_name', data: string): boolean {
return super.emit(event, data);
}
}
[SpecificClientEvents
现在将需要正确的字符串类型。