Angular: OpaqueToken или InjectionToken

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

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

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

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

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

interface Config {
  production: boolean;
  base: string;
}

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

const APP_CONFIG = new InjectionToken<Config>('APP_CONFIG');
providers: [
  {
    provide: APP_CONFIG,
    useValue: {
      production: true,
      base: ''
    }
  }
]

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

constructor(injector: Injector) {
     const config = injector.get(APP_CONFIG);
}

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

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

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