我正在使用React victory库来创建图表,而我正在使用TypeScript。我已将@types/victory包添加到我的项目中,但遗憾的是,它缺少一些我需要的 密钥 定义。对于某些接口,它缺少一些属性,因此(使用this answer),我创建了一个自定义文件,将这些属性添加到接口。
但是,现在我遇到了一个问题:为事件定义的接口定义了一个名为eventHandlers
的属性,但它又缺少一个重要的定义,它是如何定义的:
export interface EventPropTypeInterface<TTarget, TEventKey> {
/* other properties */,
eventHandlers: {
[key: string]:
{ (event: React.SyntheticEvent<any>): EventCallbackInterface<TTarget, TEventKey> } |
{ (event: React.SyntheticEvent<any>): EventCallbackInterface<TTarget, TEventKey>[] }
}
但是,问题是该函数应该允许接受第二个参数,例如(我不确定第二个参数的类型,所以我有any
):
{ (event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey> }
所以,我试图在我自己的定义中包含这个属性:
declare module "victory" {
export interface EventPropTypeInterface<TTarget, TEventKey> {
eventHandlers: {
[key: string]:
{ (event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey> } |
{ (event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey>[] }
}
}
但是现在,TypeScript抱怨index.d.ts
目录中的@typings
,说eventHandlers
必须是我定义的类型。
有没有办法使用提供的类型定义文件,并以某种方式使用我自己的定义“扩充”它,类似于我在添加新属性时对其他接口所做的操作?
答案 0 :(得分:3)
这可行。问题是这些类型没有考虑到可扩展性。
对象文字类型(例如{x: string}
)在很多情况下都很好用,但对于复杂的嵌套结构则不行。
原因是这些类型与类型别名类似,不受启用可扩展性所需的声明合并的约束。
如果eventHandlers
对象的可能值的类型被声明为interface
,则可以通过简单地添加额外的重载来轻松扩展它。
以下自包含的示例显示了在重构类型以对interface
的值类型使用eventHandlers
声明时,如何轻松扩展性:
declare module "victory" {
interface EventHandler<TTarget, TEventKey> {
(event: React.SyntheticEvent<any>): EventCallbackInterface<TTarget, TEventKey>
(event: React.SyntheticEvent<any>): EventCallbackInterface<TTarget, TEventKey>[]
}
export interface EventPropTypeInterface<TTarget, TEventKey> {
eventHandlers: {
[key: string]: EventHandler<TTarget, TEventKey>
}
}
}
declare module "victory" {
// this interface merges with the original, declaring additional overloads of the all signature
interface EventHandler<TTarget, TEventKey> {
// declare overloads
(event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey>
(event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey>[]
}
}
type EventCallbackInterface<T, U> = {}
declare namespace React {
export type SyntheticEvent<T> = {};
}
测试:
import victory = require("victory");
declare const handlerProps: victory.EventHandler<{}, {}>;
handlerProps({}, { x: 1, y: 2 }); // works fine
Here is a link to it in action
我强烈建议您向https://github.com/DefinitelyTyped/DefinitelyTyped提交一个提取请求,修改npm:@types/victory
以便以这种方式使用interface
来启用此类可扩展性。