Как сделать сервис типизированным при использовании альтернативных поставщиков классов в Angular - PullRequest
0 голосов
/ 10 мая 2018

Я пытаюсь использовать альтернативный провайдер класса . Лучший способ описать мою проблему - это на примере. У меня есть этот сервис:

export MyService {
  method() {
    // Some Code
  }
}

И я расширяю его с помощью детской службы:

export MyAnotherService extends MyService {
  anotherMethod() {
    // Some Code
  }
}

Затем укажите его в поставщике модуля приложения следующим образом:

{ provide: MyService, useClass: MyAnotherService }

Тогда я использую родительский сервис, как это:

constructor(
  private service: MyService
) {}

ngOnInit() {
  this.service.method();
  this.service.anotherMethod(); // <- Typescript complains about this line.
}

Все отлично работает, и приложение работает в браузере, за исключением того, что я получаю предупреждение TypeScript:

[ts] Property 'anotherMethod' does not exist on 'MyService'.

Можно ли заставить TypeScript осознавать тот факт, что anotherMethod действительно существует?

Примечание: Доступ к другому методу, например this.service['anotherMethod'](), решает проблему, но я хочу, чтобы TypeScript знал об этом методе.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Как правило, это может быть решено с помощью Inject, как показывает собственный ответ asker.

constructor(service: MyService) {}

аннотация типа является синтаксическим сахаром для:

constructor(@Inject(MyService) service: MyService) {}

Это то, что Injectableдекоратор предназначен для (как объяснено в этот ответ ).

Поэтому, если токен класса преобразуется в другой экземпляр класса при внедрении, его можно набрать соответственно:

constructor(@Inject(MyService) service: MyAnotherService) {}

Это решение может быть индикатором проблемы XY;допустимо только если MyService с состоянием, и должны быть одноэлементными, и используется как экземпляр MyService в одном месте, которое не может быть изменено разработчиком, но используетсякак MyAnotherService в другом месте.

В противном случае два разных провайдера должны быть объявлены и использованы в соответствующих случаях:

providers: [MyService, MyAnotherService]
0 голосов
/ 10 мая 2018

Решил проблему. Я должен использовать Inject здесь:

import { Inject } from '@angular/core';

Тогда в конструкторе:

constructor(
  @Inject(MyService) private service: MyAnotherService
) {}

Таким образом, я получу экземпляр MyAnotherService, введенный MyService при интерфейсе MyAnotherService.

...