TypeScript:覆盖和修复包的类型定义 [英] TypeScript: override and fix typing definitions for packages

查看:14
本文介绍了TypeScript:覆盖和修复包的类型定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 React pain 图表库,我正在使用 TypeScript.我已将 @types/victory 包添加到我的项目中,但不幸的是,它丢失了一堆我需要的 key 定义.对于某些接口,它缺少几个属性,因此(使用 this answer),我创建了一个自定义文件来将这些属性添加到接口中.

I'm using the React victory library for charts, and I'm using TypeScript. I have added the @types/victory package to my project, but unfortunately, it's missing a bunch of key definitions that I need. For some interfaces, it was missing a couple of properties, so (using this answer), I created a custom file to add those properties to the interfaces.

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

But, now I have a problem: the interface defined for events has a property named eventHandlers defined, but again it's missing an important definition, how it's defined:

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):

But, the problem is that the function should allow accepting a second parameter, example (I'm not sure about the type of the second argument, so I have any):

{ (event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey> }

因此,我尝试在自己的定义中包含此属性:

So, I tried to include this property in my own definition:

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 正在抱怨 @typings 目录中的 index.d.ts,说 eventHandlers 必须属于我定义的类型.

But now, TypeScript is complaining about the index.d.ts in the @typings directory, saying that eventHandlers must be of the type I have defined.

有没有办法使用提供的类型定义文件并以某种方式使用我自己的定义扩充"它,类似于我在添加新属性时对其他接口所做的操作?

Is there a way to use the provided type definition file and somehow "augment" it with my own definition similar to what I did with other interfaces when just adding new properties?

推荐答案

这行得通.问题在于定义类型时没有考虑到可扩展性.

This can work. The problem is that the types were not defined with extensibility in mind.

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

Object literal types, such as {x: string} are great in many situations, but not for complex nested structures.

原因是这些类型,类似于类型别名,服从于启用可扩展性所需的声明合并.

The reason is that these types, similar to type aliases, are not subject to the declaration merging needed to enable extensibility.

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

If the types of the possible values of the eventHandlers object were declared as an interface it could be extended with ease by simply adding additional overloads.

下面的自包含示例展示了当类型被重构为对 eventHandlers 的值类型使用 interface 声明时,扩展性是多么容易:

The following, self contained example shows how extensibility is quite easy when the types are refactored to use an interface declaration for the value type of 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/victory 以使用 interface 以这种方式启用这种可扩展性.

I strongly recommend that you submit a Pull Request to https://github.com/DefinitelyTyped/DefinitelyTyped that modifies npm:@types/victory to use an interface in this manner to enable such extensibility.

这篇关于TypeScript:覆盖和修复包的类型定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆