Angular: OpaqueToken или InjectionToken

Не успели все познакомиться с понятием OpaqueToken, как оно уже становиться deprecated. Теперь нужно использовать вместо него InjectionToken.

Давайте попробуем разобраться почему.

При том, что InjectionToken несет такую же функциональность что и OpaqueToken(более того он является наследником), он еще предоставляет возможность строго задать тип инжектируемой сущности. Особенно это удобно, когда это сложный/составной тип с внутренними свойствами.

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

Давайте разберем пример с конфигурацией приложения, которая задается через инжектируемую сущность как значение. Для начала определим интерфейс для этого типа:

[javascript]
interface Config {
production: boolean;
base: string;
}
[/javascript]

Теперь можем создать для нашей инжектируемой сущности InjectionToken и по нему задать провайдер:

[javascript]
const APP_CONFIG = new InjectionToken<Config>(‘APP_CONFIG’);
providers: [
{
provide: APP_CONFIG,
useValue: {
production: true,
base: ”
}
}
]
[/javascript]

При инжектировании нашей сущности с помощью инжектора:

[javascript]
constructor(injector: Injector) {
const config = injector.get(APP_CONFIG);
}
[/javascript]

компилятор уже знает какого типа будет config, поэтому если мы попробуем написать что-то типа:

[javascript]
this.base = config.bese; //просто опечатались
[/javascript]

компилятор сразу выдаест ошибку: Property ‘bese’ does not exist on type ‘Config’
А в случае использования OpaqueToken ошибка не будет выявлена на этапе компиляции.
Довольно удобно, правда?