From ca721c2972f44d903a0e12fae3397ab62769e649 Mon Sep 17 00:00:00 2001 From: abarghoud Date: Wed, 24 Feb 2021 20:29:09 +0100 Subject: [PATCH] feat(core): more precise type for `APP_INITIALIZER` token (#40986) This commit updates the type of the `APP_INITIALIZER` injection token to better document the expected types of values that Angular handles. Only Promises and Observables are awaited and other types of values are ignored, so the type of `APP_INITIALIZER` has been updated to `Promise | Observable | void` to reflect this behavior. BREAKING CHANGE: The type of the `APP_INITIALIZER` token has been changed to more accurately reflect the types of return values that are handled by Angular. Previously, each initializer callback was typed to return `any`, this is now `Promise | Observable | void`. In the unlikely event that your application uses the `Injector.get` or `TestBed.inject` API to inject the `APP_INITIALIZER` token, you may need to update the code to account for the stricter type. Additionally, TypeScript may report the TS2742 error if the `APP_INITIALIZER` token is used in an expression of which its inferred type has to be emitted into a .d.ts file. To workaround this, an explicit type annotation is needed, which would typically be `Provider` or `Provider[]`. Closes #40729 PR Close #40986 --- goldens/public-api/core/core.d.ts | 4 ++-- packages/core/src/application_init.ts | 8 ++++++-- packages/router/src/router_module.ts | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/goldens/public-api/core/core.d.ts b/goldens/public-api/core/core.d.ts index 52ac3b1f5a..99595a7ec4 100644 --- a/goldens/public-api/core/core.d.ts +++ b/goldens/public-api/core/core.d.ts @@ -25,12 +25,12 @@ export declare const APP_BOOTSTRAP_LISTENER: InjectionToken<((compRef: Component export declare const APP_ID: InjectionToken; -export declare const APP_INITIALIZER: InjectionToken<(() => void)[]>; +export declare const APP_INITIALIZER: InjectionToken Observable | Promise | void)[]>; export declare class ApplicationInitStatus { readonly done = false; readonly donePromise: Promise; - constructor(appInits: (() => any)[]); + constructor(appInits: ReadonlyArray<() => Observable | Promise | void>); } export declare class ApplicationModule { diff --git a/packages/core/src/application_init.ts b/packages/core/src/application_init.ts index 76707e8aa0..b89ed0908a 100644 --- a/packages/core/src/application_init.ts +++ b/packages/core/src/application_init.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ +import {Observable} from 'rxjs'; import {Inject, Injectable, InjectionToken, Optional} from './di'; import {isObservable, isPromise} from './util/lang'; import {noop} from './util/noop'; @@ -28,7 +29,9 @@ import {noop} from './util/noop'; * * @publicApi */ -export const APP_INITIALIZER = new InjectionToken void>>('Application Initializer'); +export const APP_INITIALIZER = + new InjectionToken Observable| Promise| void>>( + 'Application Initializer'); /** * A class that reflects the state of running {@link APP_INITIALIZER} functions. @@ -43,7 +46,8 @@ export class ApplicationInitStatus { public readonly donePromise: Promise; public readonly done = false; - constructor(@Inject(APP_INITIALIZER) @Optional() private appInits: (() => any)[]) { + constructor(@Inject(APP_INITIALIZER) @Optional() private readonly appInits: + ReadonlyArray<() => Observable| Promise| void>) { this.donePromise = new Promise((res, rej) => { this.resolve = res; this.reject = rej; diff --git a/packages/router/src/router_module.ts b/packages/router/src/router_module.ts index 26e2a4ce6d..810fd68a11 100644 --- a/packages/router/src/router_module.ts +++ b/packages/router/src/router_module.ts @@ -584,7 +584,7 @@ export function getBootstrapListener(r: RouterInitializer) { export const ROUTER_INITIALIZER = new InjectionToken<(compRef: ComponentRef) => void>('Router Initializer'); -export function provideRouterInitializer() { +export function provideRouterInitializer(): ReadonlyArray { return [ RouterInitializer, {