TypeScript 声明 class 未找到

TypeScript declare class not found

我有一个 class 扩展了 EventEmmiter class.

我希望 IntelliSense 显示您可以收听的不同事件并帮助自动完成它们,所以我想到了这个:

//Imports from index.ts
import {
    CommandContext,
    CommandErrorContext,
    CommandHandler
} from '../../';
import { EventEmitter } from 'events';

export class CommandHandler extends CommandHandlerEvents {

    constructor() {
        super();
    }

}

export declare class CommandHandlerEvents extends EventEmitter {
    on(event: string, listener: Function): this;
    on(event: 'failure', listener: (handler: CommandHandler, context: CommandErrorContext) => void): this;
    on(event: 'success', listener: (handler: CommandHandler, context: CommandContext) => void): this;

    once(event: string, listener: Function): this;
    once(event: 'failure', listener: (handler: CommandHandler, context: CommandErrorContext) => void): this;
    once(event: 'success', listener: (handler: CommandHandler, context: CommandContext) => void): this;

    emit(event: string, args: any[]): boolean;
    emit(event: 'failure', args: [CommandHandler, CommandErrorContext]): boolean;
    emit(event: 'success', args: [CommandHandler, CommandContext]): boolean;
}

上面的代码完全符合我的要求,但是当我创建 CommandHandler class 的实例时,它会抛出此错误:

Uncaught ReferenceError: CommandHandlerEvents is not defined

我读到有人使用界面来做同样的事情,但是当我将 CommandHandlerEventsdeclare class 更改为 interface 时,IntelliSense 上不再显示这些建议。

期望结果示例:image

当您 declare class 或使用 interface 时,您只是在 编译时 向类型系统添加内容].您没有在 运行时 添加任何内容。如果你看,没有任何名为 CommandHandlerEvents 的东西被发送到 JavaScript。 declare 关键字告诉编译器你所说的东西将在运行时存在,因为它将由运行代码的任何运行时环境提供。

您希望 EventEmitter 的所有用法都具有您所说的特定提示吗?如果是这样,您可以module augmentation 添加此类型信息:

import { EventEmitter } from 'events';
declare module 'events' {
  interface EventEmitter {
    on(event: string, listener: Function): this;
    on(event: 'failure', listener: (handler: EventEmitter, context: CommandErrorContext) => void): this;
    on(event: 'success', listener: (handler: EventEmitter, context: CommandContext) => void): this;

    once(event: string, listener: Function): this;
    once(event: 'failure', listener: (handler: EventEmitter, context: CommandErrorContext) => void): this;
    once(event: 'success', listener: (handler: EventEmitter, context: CommandContext) => void): this;

    emit(event: string, args: any[]): boolean;
    emit(event: 'failure', args: [EventEmitter, CommandErrorContext]): boolean;
    emit(event: 'success', args: [EventEmitter, CommandContext]): boolean;
  }
}

const eventEmitter = new EventEmitter();
eventEmitter.once(...) // get hints

或者您真的想要在运行时比 EventEmitter 更具体的 class CommandHandler 吗?您也可以使用 declaration merging 来做到这一点:

import { EventEmitter } from 'events';
export class CommandHandler extends EventEmitter { }
export interface CommandHandler {
  on(event: string, listener: Function): this;
  on(event: 'failure', listener: (handler: CommandHandler, context: CommandErrorContext) => void): this;
  on(event: 'success', listener: (handler: CommandHandler, context: CommandContext) => void): this;

  once(event: string, listener: Function): this;
  once(event: 'failure', listener: (handler: CommandHandler, context: CommandErrorContext) => void): this;
  once(event: 'success', listener: (handler: CommandHandler, context: CommandContext) => void): this;

  emit(event: string, args: any[]): boolean;
  emit(event: 'failure', args: [CommandHandler, CommandErrorContext]): boolean;
  emit(event: 'success', args: [CommandHandler, CommandContext]): boolean;
}

const commandHandler = new CommandHandler();
commandHandler.once(...) // get hints

希望对您有所帮助!