Typescript - как реализовать часть интерфейса зависимости? - PullRequest
0 голосов
/ 19 апреля 2020

Я пытаюсь создать свой собственный класс логгера. Он содержит ссылку на winston.Logger как this.logger. У регистратора Уинстона есть такие методы:

    error: LeveledLogMethod;
    warn: LeveledLogMethod;
// etc...

LeveledLogMethod определяется как:

  interface LeveledLogMethod {
    (message: string, callback: LogCallback): Logger;
    (message: string, meta: any, callback: LogCallback): Logger;
    (message: string, ...meta: any[]): Logger;
    (infoObject: object): Logger;
  }

Для моего регистратора я хочу, чтобы он поддерживал, например, debug, info и error методы - но - мне также все равно, что эти методы реализуют все LeveledLogMethod. Итак, я определю свой собственный интерфейс для своих методов ведения журнала:

interface LogMethod {
  (message: string): void;
  // (message: string, meta: any): void;
  // (message: string, ...meta: any[]): void;
  (infoObject: object): void;
}

Чтобы упростить его, я закомментировал часть того, что я хочу реализовать. Тем не менее, этого достаточно, чтобы ошибиться. По сути, мой LogMethod интерфейс является подмножеством LeveledLogMethod.

Уинстона. Однако, когда я пытаюсь реализовать свои LogMethod как:

  public debug: LogMethod = (arg: string | object) => {
    this.logger.debug(arg);
  };
  // `this.logger` is a `winston.Logger` and `this.logger.debug` is a `LeveledLogMethod`.

, я получаю:

No overload matches this call.
  Overload 1 of 4, '(message: string, ...meta: any[]): Logger', gave the following error.
    Argument of type 'string | object' is not assignable to parameter of type 'string'.
      Type 'object' is not assignable to type 'string'.
  Overload 2 of 4, '(infoObject: object): Logger', gave the following error.
    Argument of type 'string | object' is not assignable to parameter of type 'object'.
      Type 'string' is not assignable to type 'object'.

Но я знаю, что это должно работать, так как независимо от того, является ли arg string или object, оно соответствует одной из перегрузок, определенных в LeveledLogMethod.

Как я могу заставить компилятор Typescript позволить мне сделать это за исключением // @ts-ignore или приведения arg к string или object?

1 Ответ

0 голосов
/ 19 апреля 2020

Как говорится в ошибке, arg должно точно соответствовать одной из LeveledLogMethod подписей, но не соответствует ни первой, ни второй. Хотя код правильный, компилятор смотрит на него с другой точки зрения.

Я могу предложить вам добавить проверку типа вместо приведения:

public debug: LogMethod = (arg: string | object) => {
  if (typeof arg === 'string') {
    this.logger.debug(arg);
  } else {
    this.logger.debug(arg);
  }
};

Playground

...