通过打字稿声明合并覆盖(重新引入)属性

问题描述 投票:0回答:1

假设

Event
GlobalEventHandlersEventMap
的基本/内置声明如下所示:

// lib.dom.d.ts

interface Event {
    /**
     * Returns the type of event, e.g. "click", "hashchange", or "submit".
     */
    readonly type: string;   // <-- note this part
}

interface GlobalEventHandlersEventMap {
    click: MouseEvent;
    //... all sorts of other built in events...
}

注意:在我的应用程序的上下文中,我知道

type
将始终是内置事件类型(
GlobalEventHandlersEventMap
的键)或自定义事件类型(可以通过声明合并添加 -如下例所示)。

在其他地方的一些代码中,我有类似这样的内容:

class EventTriggered {
    constructor(
        readonly eventName: keyof GlobalEventHandlersEventMap
    ) {}
}

我想像这样构建一个实例:

const et = new EventTriggered(event.type);

这会导致错误,因为 eventName 应该是上述映射的键,但它收到的是一个字符串(因为

Event.type
是这样声明的)。

通过减速合并,我可以“注册”或“添加”自定义事件,如下所示:

// global.d.ts
interface GlobalEventHandlersEventMap {
    myEvent: CustomEvent;     // <--- this will be added to the original "list"
}                             //      of events from above, thanks to generics

但是,如果我尝试同样的方法来“覆盖”

type
属性,它将不起作用......大概是因为它只是作为属性的变体添加。

// global.d.ts
interface Event {
    readonly type: keyof GlobalEventHandlersEventMap;
}

接下来发生的事情是之前的错误仍然出现,但现在我的 IDE 显示

type
有两个声明: property variation


我也看到了这个问题,但感觉不同 - 一方面,我没有得到与那个相同的错误:TypeScript声明合并 - 更改属性类型

typescript redeclaration
1个回答
0
投票

好吧,我个人认为声明合并不是一个功能,而是一个错误:)

如果我理解正确,你想要一个联合类型,该联合类型将从

EventMap
的键名称中获取,但有时可能会有一些其他字符串不属于键名称联合的一部分。

可以更换

readonly eventName: keyof GlobalEventHandlersEventMap

readonly eventName: string

但是这种方法会让您丢失所有关键名称信息。 您可以使用打字稿的一些小技巧,如下所示。

readonly eventName: keyof GlobalEventHandlersEventMap | ({} & string)

这样 eventName 将是键名或任何其他字符串。自动完成也适用于此变量。

© www.soinside.com 2019 - 2024. All rights reserved.