javascript - 覆盖 Typescript 声明类型以在 DOM 的 Event 类上声明静态方法

标签 javascript typescript

在用 Javascript 编写的 Web 应用程序中,我通过添加“静态方法”(我使用引号是因为它是一个非常近似的描述)使用以下代码:

Event.stop = function(event) {
    if(event) {
        event.stopPropagation();
        event.preventDefault();
    }
};

这很好用。这是一个例子:

document.getElementById('xxx').addEventListener('click', event => Event.stop(event));

Visual Studio Code 是我最喜欢的编辑器,我广泛使用嵌入式 Typescript 类型检查器。它用以下错误标记上面的示例:

Property 'stop' does not exist on type '{ new (typeArg: string, eventInitDict?: EventInit): Event; prototype: Event; readonly AT_TARGET: ...'.

这是完全正确的,因为在 vanilla Javascript 中 Event 没有“stop”属性。

然后,我创建了一个自定义的 Typescript 类型声明文件 xxx.d.ts 来向 Typescript 声明这个“停止”属性。

我尝试了以下方法,但均无效:

interface EventConstructor {
    stop(event: Event);
}

或:

interface Event {
    stop(event: Event);
    static stop(event: Event);
}

甚至:

var Event: {
    stop(event: Event);
};

向 Typescript 声明“停止”函数的正确方法是什么?

有关信息,这是 lib.dom.d.ts 中的 Event 声明:

interface Event {
    readonly bubbles: boolean;
    cancelBubble: boolean;
    readonly cancelable: boolean;
    readonly composed: boolean;
    readonly currentTarget: EventTarget | null;
    readonly defaultPrevented: boolean;
    readonly eventPhase: number;
    readonly isTrusted: boolean;
    returnValue: boolean;
    readonly srcElement: Element | null;
    readonly target: EventTarget | null;
    readonly timeStamp: number;
    readonly type: string;
    deepPath(): EventTarget[];
    initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void;
    preventDefault(): void;
    stopImmediatePropagation(): void;
    stopPropagation(): void;
    readonly AT_TARGET: number;
    readonly BUBBLING_PHASE: number;
    readonly CAPTURING_PHASE: number;
    readonly NONE: number;
}
declare var Event: {
    prototype: Event;
    new(typeArg: string, eventInitDict?: EventInit): Event;
    readonly AT_TARGET: number;
    readonly BUBBLING_PHASE: number;
    readonly CAPTURING_PHASE: number;
    readonly NONE: number;
};

最佳答案

不幸的是,根据 Event 的当前定义,没有办法做到这一点。

例如,我们可以为 Array 执行此操作,因为 Array 被声明为 ArrayContructor 类型的变量。

interface ArrayConstructor {
    ...
}

declare const Array: ArrayConstructor;

所以当我们想要向数组添加静态方法时,我们可以利用接口(interface)的合并行为。由于 ArrayConstructor 是一个接口(interface),我们可以重新声明它并添加额外的成员,typescript 将合并 ArrayConstructor 的两个声明,从而改变 Array 的有效类型

对于 Event 变量的类型声明为内联,我们不能使用相同的方法,因为没有接口(interface)可以合并,我们不能合并变量的类型:

declare var Event: {
    prototype: Event;
    new(typeArg: string, eventInitDict?: EventInit): Event;
    ...
};

关于javascript - 覆盖 Typescript 声明类型以在 DOM 的 Event 类上声明静态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51386266/

相关文章:

typescript - 如何在 typescript 中编写柯里化(Currying)函数的类型签名

typescript - 为什么联合中使用的对象的属性具有any类型?

javascript - 如何将扩展运算符传递给函数参数

javascript - TinyMCE Smileys 插件 - 更改插入笑脸的宽度

javascript - 如何以 Angular 将数据从 View 传递到布局

angular - TS 类型缺少以下属性

angular - 类型“订阅”上不存在属性 'subscribe'

javascript - 表格特定列的范围搜索过滤器

javascript - 如何通过手动输入数字和使用angular2过滤来过滤内容

javascript - 将数据从本地SQL Server同步到Internet上的MySQL Server(实时服务器)