10

我正在为图表使用React 胜利库,并且正在使用 TypeScript。我已将@types/victory包添加到我的项目中,但不幸的是,它缺少我需要的一堆关键定义。对于某些接口,它缺少几个属性,所以(使用这个答案),我创建了一个自定义文件来将这些属性添加到接口中。

但是,现在我有一个问题:为事件定义的接口有一个名为eventHandlersdefined 的属性,但它又缺少一个重要的定义,它是如何定义的:

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必须是我定义的类型。

有没有办法使用提供的类型定义文件,并以某种方式用我自己的定义“增强”它,类似于我在添加新属性时对其他接口所做的事情?

4

1 回答 1

4

这可以工作。问题是这些类型的定义没有考虑到可扩展性。

对象字面量类型,例如{x: string}在许多情况下都很好,但不适用于复杂的嵌套结构。

原因是这些类型,类似于类型别名,不受启用可扩展性所需的声明合并的约束。

如果对象的可能值的类型eventHandlers被声明为 aninterface它可以通过简单地添加额外的重载来轻松扩展。

下面的自包含示例显示了当类型被重构为使用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

这是一个链接到它的行动

我强烈建议您向https://github.com/DefinitelyTyped/DefinitelyTyped提交一个拉取请求,该请求修改npm:@types/victoryinterface以这种方式使用以启用这种可扩展性。

于 2018-02-13T17:38:39.183 回答