TypeScript добавить перегрузку к методу в другом файле определений - PullRequest
2 голосов
/ 29 апреля 2020

Учитывая класс, определенный в стороннем d.ts файле определений, который я не могу отредактировать:

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

Метод someMethod требует определенного типа для параметра b в зависимости от типа параметр a. Однако файл определений не представляет это ограничение как any.

Возможно ли добавить определения перегрузки для someMethod в мои собственные d.ts - без необходимости переопределять ВСЕ методы / подпорки на оригинальное определение? Я знаю, что это можно сделать легко, если бы вместо этого класс был интерфейсом.

Примерно так:

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

Вышеуказанное заменяет первоначальное определение класса, что означает, что теперь only содержит мой метод переопределения, а не moreMethods() et c.

На самом деле, этот вопрос касается компонента Angular MatDialog, который определяет open as:

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>;

UPDATE Так следующий @ ответ 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, определенный в компоненте angular. Есть ли какая-то разница, потому что он добавляет к внешнему npm модулю?

1 Ответ

0 голосов
/ 06 мая 2020

В TS объявлении class также создайте интерфейс с тем же именем, поэтому теоретически вы можете увеличить сигнатуру MyClass.open извне, используя метод слияния интерфейса.

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

Однако это не так собираюсь решить вашу проблему. Объединение интерфейсов может только добавить к существующей подписи, вы можете перегрузить метод .open(), но никогда не переопределять его.

Эта существующая подпись .open() уже слишком свободна. Хотя вы можете перегружать его более строгой подписью, но все, что нарушает ограничение, откатится к существующей свободной подписи, тем самым лишит законной силы ограничение и не вызовет ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...