get устарел: из v4.0.0 use Type <t> или InjectionToken <t>

После перехода на Angular 5.2.3 и запуска ng cli с правилом линтера "deprecation": true во многих моих тестах я получаю следующую ошибку:

get is deprecated: from v4.0.0 use Type<T> or InjectionToken<T>

Жалоба похожа на

fixture.debugElement.injector.get(MyService)

с классом MyService, используемым для внедрения зависимостей.

Я затрудняюсь догадаться, каким должен быть новый синтаксис, так как

fixture.debugElement.injector.get<MyService>(MyService)

выдает ошибку компиляции, которая Argument of type 'typeof MyService' is not assignable to parameter of type 'Type<MyService> | InjectionToken<MyService>'.

Как правильно использовать инжектор, чтобы избежать ошибок устаревания?

Изменение: см. ответ ниже, для обновления Angular9.

Редактировать: Кажется, это связано с MyService, являющимся абстрактным классом. Если я использую неабстрактный класс, синтаксис .get<T>(T) работает.

Редактировать: Исправление, по-видимому, в ожидании некоторой работы PR - https://github.com/angular/angular/pull/25222

Ответы

Ответ 1

Лучше вы можете попытаться преобразовать свой сервис в Тип, а затем использовать инжектор, например, так:

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

fixture.debugElement.injector.get<MyService>(MyService as Type<MyService>)

Ответ 2

В качестве временного решения вы можете попробовать следующее:

fixture.debugElement.injector.get<MyService>(MyService as any)

Ответ 3

Я работал над этим, определяя токен ввода:

export const DATA_SERVICE = new InjectionToken('DataService');

и используя его для псевдонима моей службы в модуле:

...
providers = [
    { provide: DataService, useFactory: dataServiceFactory },
    { provide: DATA_SERVICE, useExisting: DataService }
]
...

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

this.dataService = injector.get(DATA_SERVICE);

В моем случае DataService является абстрактным классом, и у меня есть две конкретные (@Injectable) реализации для переключения между @Injectable данными и реальными данными веб-сервиса. Соответствующая версия dataServiceFactory методе dataServiceFactory.

Есть две перегрузки для вызова injector.get() и я думаю, что без InjectionToken вызывается устаревшая перегрузка, потому что система типов не распознает тип typeof DataService как InjectionToken.

Интересно, что все инъекции этой услуги компонентам через конструкторы, такие как:

constructor(
    ds: DataService
) { }

в настоящее время работаю. Будут ли они работать, когда устаревшая перегрузка get() будет удалена в будущем?

Я думаю, что это вопрос для команды Angular.

Ответ 4

ОБНОВЛЕНИЕ: для Angular9 синтаксис был изменен на следующий:

TestBed.inject<IDataService>(IDataService).

Это также работает для абстрактных классов.

В VSCode вы можете исправить большинство ваших случаев с помощью этого

FIND: TestBed.get\(([^\)]+)\) as .*;
REPLACE: TestBed.inject<$1>($1);

PRE Angular 9. Так что, похоже, это связано с абстрактными и неабстрактными классами.

Я разместил свои выводы здесь: https://github.com/angular/angular/issues/22063 на случай, если кто-то столкнется с той же проблемой.

Ответ 5

Я продолжал получать это предупреждение, даже если я изменил код в соответствии с недревесенным get(). После обновления Angular CLI с 6.0.0. 6.2.6 предупреждение ушло.