【问题标题】:TypeScript add overload to method in another definitions fileTypeScript 将重载添加到另一个定义文件中的方法
【发布时间】:2020-08-13 06:16:49
【问题描述】:

鉴于我无法编辑的第 3 方 d.ts 定义文件中定义的类:

export declare class MyClass {
  someMethod(a: any, b: any);
  moreMethods();
  // lots more methods here
}

someMethod 方法需要根据参数a 的类型为参数b 指定特定类型。但是,定义文件并不表示该约束,因为两者都为 any

是否可以在我自己的 d.ts 中添加 someMethod 的重载定义 - 而不必重新定义原始定义上的所有方法/道具?我知道如果类是一个接口,它可以很容易地完成。

类似这样的:

export declare class MyClass {
  // add override declaration to ensure `b` is a string if `a` is a number.
  someMethod(a: number, b: string); 
}

以上似乎替换原来的类定义,这意味着它现在只有有我的覆盖方法,而不是moreMethods()等。

实际上,这个问题与定义 open 的 Angular MatDialog 组件有关:

open<T, D = any, R = any>(
   componentOrTemplateRef: ComponentType<T> | TemplateRef<T>, 
   config?: MatDialogConfig<D>): MatDialogRef<T, R>;

这意味着我可以实例化一个对话框,但传入错误的对话框数据对象(类型D)。我想添加如下定义:

// ensure that FooDialogComponent is passed FooDialogData for config
open<T, D = any, R = any>(
   componentOrTemplateRef: typeof FooDialogComponent, 
   config?: MatDialogConfig<FooDialogData>): MatDialogRef<T, R>;
// ensure that BarDialogComponent is passed BarDialogData for config
open<T, D = any, R = any>(
   componentOrTemplateRef: typeof BarDialogComponent, 
   config?: MatDialogConfig<BarDialogData>): MatDialogRef<T, R>;

更新 所以按照@hackape 的回答,我创建了这个代码(https://www.typescriptlang.org/play/index.html#code/KYDwDg9gTgLgBAWwgEwK4BthwLIE9soZYDeAUHHKJLHAMboCGAzk3ACrBPxkUULAwAFigAUDAFxwGAO1wBKOMTgBfcrxkQhwKNgHDkYyTPmKVas6tJVo8ZMHoMoWRIUw58rkmus0AltJhtADMGWiwOLkVzOAB6GLgIADdtdAgGZDgAd18hOCYwe18g31o4GFwC6P4hUQk4aVQEACNtOUlEiF9kAG41VUtSRMcpAEY4AF564Ez3AjRMADoImBE5Xri4f0D0dF8mYGl9hKCg7VYmzUE4QW0scTlSBhGF6v0RACYRgGY1x+eNLQ6PSiEZrIA),它按预期工作。

然而,如前所述,我使用它来向 Angular Mat Dialog 组件添加重载,但它似乎无法使用它。

declare module '@angular/material/dialog' {
    export interface MatDialog  {
        someTestMethod(): void;
    }
}

现在使用对话框组件的任何地方都只会看到someTestMethod(),而不是角度组件中定义的 MatDialog 类上的所有现有方法。是否有一些区别,因为它是添加到外部 npm 模块?

【问题讨论】:

  • 类声明也会创建一个接口声明,所以将export declare class MyClass { 更改为export declare interface MyClass { 是否可行?接口似乎与类不同。

标签: angular typescript angular-material


【解决方案1】:

在 TS 中声明 class 也会创建一个同名的接口,因此理论上您可以使用接口合并技术从外部扩充 MyClass.open 签名。

declare module 'existing-module' {
  interface MyClass {
    someMethod(a: number, b: string): void;
  }
}

但是,这并不能解决您的问题。接口合并只能添加到现有的签名,你可以重载.open()方法,但永远不要覆盖它。

现有的.open() 签名已经太松散了。虽然你可以用更严格的签名重载它,但是任何违反约束的东西都会回退到现有的松散签名,从而使约束无效并且不会引发错误。

【讨论】:

  • 谢谢。同意它不会引发错误,只是希望智能感知帮助传递特定组件的当前对话数据。另外,我的意思是超载而不是覆盖,对不起。将使用更多信息更新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-06
  • 2013-03-12
  • 2010-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
相关资源
最近更新 更多