TypeScript:覆盖并修复包的类型定义
TypeScript: override and fix typing definitions for packages
我正在使用 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 ),我创建了一个自定义文件以将这些属性添加到界面。
但是,现在我遇到了一个问题:为事件定义的接口有一个名为 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 正在抱怨 @typings
目录中的 index.d.ts
,说 eventHandlers
必须是我定义的类型。
有没有办法使用提供的类型定义文件并以某种方式"augment"它与我自己的定义类似,就像我在添加新属性时对其他接口所做的那样?
这可行。问题是类型的定义没有考虑可扩展性。
对象文字类型,例如 {x: string}
在许多情况下都很好,但不适用于复杂的嵌套结构。
原因是这些类型与类型别名类似,不受启用扩展性所需的声明合并的约束。
如果 eventHandlers
对象的可能值的类型被声明为 interface
它可以通过简单地添加额外的重载来轻松扩展。
下面的自包含示例展示了当类型被重构为对 eventHandlers
的值类型使用 interface
声明时,可扩展性是多么容易:
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
以实现这种可扩展性。
我正在使用 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
但是,现在我遇到了一个问题:为事件定义的接口有一个名为 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 正在抱怨 @typings
目录中的 index.d.ts
,说 eventHandlers
必须是我定义的类型。
有没有办法使用提供的类型定义文件并以某种方式"augment"它与我自己的定义类似,就像我在添加新属性时对其他接口所做的那样?
这可行。问题是类型的定义没有考虑可扩展性。
对象文字类型,例如 {x: string}
在许多情况下都很好,但不适用于复杂的嵌套结构。
原因是这些类型与类型别名类似,不受启用扩展性所需的声明合并的约束。
如果 eventHandlers
对象的可能值的类型被声明为 interface
它可以通过简单地添加额外的重载来轻松扩展。
下面的自包含示例展示了当类型被重构为对 eventHandlers
的值类型使用 interface
声明时,可扩展性是多么容易:
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
以实现这种可扩展性。