From c283b64c5e2613bd9e56ebdcb4cfdedec18eb297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mis=CC=8Cko=20Hevery?= Date: Tue, 3 Jan 2017 16:54:46 -0800 Subject: [PATCH] feat(core): Add type information to injector.get() (#13785) - Introduce `InjectionToken` which is a parameterized and type-safe version of `OpaqueToken`. DEPRECATION: - `OpaqueToken` is now deprecated, use `InjectionToken` instead. - `Injector.get(token: any, notFoundValue?: any): any` is now deprecated use the same method which is now overloaded as `Injector.get(token: Type|InjectionToken, notFoundValue?: T): T;`. Migration - Replace `OpaqueToken` with `InjectionToken` and parameterize it. - Migrate your code to only use `Type` or `InjectionToken` as injection tokens. Using other tokens will not be supported in the future. BREAKING CHANGE: - Because `injector.get()` is now parameterize it is possible that code which used to work no longer type checks. Example would be if one injects `Foo` but configures it as `{provide: Foo, useClass: MockFoo}`. The injection instance will be that of `MockFoo` but the type will be `Foo` instead of `any` as in the past. This means that it was possible to call a method on `MockFoo` in the past which now will fail type check. See this example: ``` class Foo {} class MockFoo extends Foo { setupMock(); } var PROVIDERS = [ {provide: Foo, useClass: MockFoo} ]; ... function myTest(injector: Injector) { var foo = injector.get(Foo); // This line used to work since `foo` used to be `any` before this // change, it will now be `Foo`, and `Foo` does not have `setUpMock()`. // The fix is to downcast: `injector.get(Foo) as MockFoo`. foo.setUpMock(); } ``` PR Close #13785 --- modules/@angular/benchpress/index.ts | 2 +- .../@angular/benchpress/src/common_options.ts | 32 ++++++++-------- .../benchpress/src/metric/multi_metric.ts | 4 +- .../benchpress/src/metric/perflog_metric.ts | 4 +- .../src/reporter/console_reporter.ts | 6 +-- .../src/reporter/json_file_reporter.ts | 4 +- .../benchpress/src/reporter/multi_reporter.ts | 4 +- .../benchpress/src/sample_description.ts | 2 +- .../validator/regression_slope_validator.ts | 6 +-- .../src/validator/size_validator.ts | 4 +- .../benchpress/src/web_driver_extension.ts | 4 +- .../common/src/location/location_strategy.ts | 4 +- .../directives/ng_component_outlet_spec.ts | 4 +- .../integrationtest/src/entry_components.ts | 4 +- .../integrationtest/src/features.ts | 8 ++-- .../integrationtest/src/module_fixtures.ts | 4 +- .../compiler/src/aot/static_reflector.ts | 22 ++++++----- .../compiler/src/jit/compiler_factory.ts | 4 +- .../compiler/src/metadata_resolver.ts | 4 +- .../src/template_parser/template_parser.ts | 4 +- modules/@angular/compiler/src/url_resolver.ts | 3 +- modules/@angular/core/src/application_init.ts | 4 +- modules/@angular/core/src/application_ref.ts | 11 +++--- .../@angular/core/src/application_tokens.ts | 12 +++--- modules/@angular/core/src/di.ts | 2 +- .../@angular/core/src/di/injection_token.ts | 36 +++++++++++++++++- modules/@angular/core/src/di/injector.ts | 8 ++++ modules/@angular/core/src/di/provider.ts | 8 ++-- modules/@angular/core/src/i18n/tokens.ts | 8 ++-- modules/@angular/core/src/linker/compiler.ts | 4 +- modules/@angular/core/src/metadata/di.ts | 4 +- .../core/test/linker/integration_spec.ts | 4 +- .../test/linker/ng_module_integration_spec.ts | 13 ++++--- .../linker/regression_integration_spec.ts | 12 +++--- modules/@angular/core/testing/test_bed.ts | 7 ++-- .../examples/core/di/ts/injector_spec.ts | 12 +++++- .../examples/core/di/ts/provider_spec.ts | 10 ++--- .../src/directives/control_value_accessor.ts | 4 +- .../@angular/forms/src/directives/shared.ts | 5 +-- modules/@angular/forms/src/validators.ts | 10 +++-- modules/@angular/http/test/http_spec.ts | 4 +- .../platform-browser/src/dom/dom_tokens.ts | 4 +- .../src/dom/events/event_manager.ts | 7 +++- .../src/dom/events/hammer_gestures.ts | 4 +- .../src/web_workers/shared/api.ts | 4 +- .../web_workers/worker/location_providers.ts | 3 +- .../platform-webworker/src/worker_render.ts | 7 ++-- .../router/src/router_config_loader.ts | 5 ++- modules/@angular/router/src/router_module.ts | 9 +++-- modules/@angular/router/upgrade.ts | 7 ++-- .../test/aot/integration/injection_spec.ts | 6 +-- .../angular1_router/src/module_template.js | 2 +- tools/public_api_guard/common/index.d.ts | 2 +- tools/public_api_guard/core/index.d.ts | 37 +++++++++++++------ .../public_api_guard/core/testing/index.d.ts | 4 +- tools/public_api_guard/forms/index.d.ts | 6 +-- .../platform-browser/index.d.ts | 6 +-- .../platform-webworker/index.d.ts | 2 +- tools/public_api_guard/router/index.d.ts | 4 +- 59 files changed, 255 insertions(+), 175 deletions(-) diff --git a/modules/@angular/benchpress/index.ts b/modules/@angular/benchpress/index.ts index e8f3af4f2f018..2203627648e5c 100644 --- a/modules/@angular/benchpress/index.ts +++ b/modules/@angular/benchpress/index.ts @@ -9,7 +9,7 @@ // Must be imported first, because angular2 decorators throws on load. import 'reflect-metadata'; -export {Injector, OpaqueToken, Provider, ReflectiveInjector} from '@angular/core'; +export {InjectionToken, Injector, Provider, ReflectiveInjector} from '@angular/core'; export {Options} from './src/common_options'; export {MeasureValues} from './src/measure_values'; export {Metric} from './src/metric'; diff --git a/modules/@angular/benchpress/src/common_options.ts b/modules/@angular/benchpress/src/common_options.ts index 255862e629d31..12125c962beef 100644 --- a/modules/@angular/benchpress/src/common_options.ts +++ b/modules/@angular/benchpress/src/common_options.ts @@ -6,26 +6,26 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '@angular/core'; +import {InjectionToken} from '@angular/core'; import * as fs from 'fs'; export class Options { - static SAMPLE_ID = new OpaqueToken('Options.sampleId'); - static DEFAULT_DESCRIPTION = new OpaqueToken('Options.defaultDescription'); - static SAMPLE_DESCRIPTION = new OpaqueToken('Options.sampleDescription'); - static FORCE_GC = new OpaqueToken('Options.forceGc'); + static SAMPLE_ID = new InjectionToken('Options.sampleId'); + static DEFAULT_DESCRIPTION = new InjectionToken('Options.defaultDescription'); + static SAMPLE_DESCRIPTION = new InjectionToken('Options.sampleDescription'); + static FORCE_GC = new InjectionToken('Options.forceGc'); static NO_PREPARE = () => true; - static PREPARE = new OpaqueToken('Options.prepare'); - static EXECUTE = new OpaqueToken('Options.execute'); - static CAPABILITIES = new OpaqueToken('Options.capabilities'); - static USER_AGENT = new OpaqueToken('Options.userAgent'); - static MICRO_METRICS = new OpaqueToken('Options.microMetrics'); - static USER_METRICS = new OpaqueToken('Options.userMetrics'); - static NOW = new OpaqueToken('Options.now'); - static WRITE_FILE = new OpaqueToken('Options.writeFile'); - static RECEIVED_DATA = new OpaqueToken('Options.receivedData'); - static REQUEST_COUNT = new OpaqueToken('Options.requestCount'); - static CAPTURE_FRAMES = new OpaqueToken('Options.frameCapture'); + static PREPARE = new InjectionToken('Options.prepare'); + static EXECUTE = new InjectionToken('Options.execute'); + static CAPABILITIES = new InjectionToken('Options.capabilities'); + static USER_AGENT = new InjectionToken('Options.userAgent'); + static MICRO_METRICS = new InjectionToken('Options.microMetrics'); + static USER_METRICS = new InjectionToken('Options.userMetrics'); + static NOW = new InjectionToken('Options.now'); + static WRITE_FILE = new InjectionToken('Options.writeFile'); + static RECEIVED_DATA = new InjectionToken('Options.receivedData'); + static REQUEST_COUNT = new InjectionToken('Options.requestCount'); + static CAPTURE_FRAMES = new InjectionToken('Options.frameCapture'); static DEFAULT_PROVIDERS = [ {provide: Options.DEFAULT_DESCRIPTION, useValue: {}}, {provide: Options.SAMPLE_DESCRIPTION, useValue: {}}, diff --git a/modules/@angular/benchpress/src/metric/multi_metric.ts b/modules/@angular/benchpress/src/metric/multi_metric.ts index 85617736541e3..47310e74835cf 100644 --- a/modules/@angular/benchpress/src/metric/multi_metric.ts +++ b/modules/@angular/benchpress/src/metric/multi_metric.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injector, OpaqueToken} from '@angular/core'; +import {InjectionToken, Injector} from '@angular/core'; import {Metric} from '../metric'; @@ -60,4 +60,4 @@ function mergeStringMaps(maps: {[key: string]: string}[]): {[key: string]: strin return result; } -const _CHILDREN = new OpaqueToken('MultiMetric.children'); +const _CHILDREN = new InjectionToken('MultiMetric.children'); diff --git a/modules/@angular/benchpress/src/metric/perflog_metric.ts b/modules/@angular/benchpress/src/metric/perflog_metric.ts index 86d34c390f7ea..d1371c826fbbb 100644 --- a/modules/@angular/benchpress/src/metric/perflog_metric.ts +++ b/modules/@angular/benchpress/src/metric/perflog_metric.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, Injectable, OpaqueToken} from '@angular/core'; +import {Inject, Injectable, InjectionToken} from '@angular/core'; import {Options} from '../common_options'; import {Metric} from '../metric'; @@ -18,7 +18,7 @@ import {PerfLogEvent, PerfLogFeatures, WebDriverExtension} from '../web_driver_e */ @Injectable() export class PerflogMetric extends Metric { - static SET_TIMEOUT = new OpaqueToken('PerflogMetric.setTimeout'); + static SET_TIMEOUT = new InjectionToken('PerflogMetric.setTimeout'); static PROVIDERS = [ PerflogMetric, { provide: PerflogMetric.SET_TIMEOUT, diff --git a/modules/@angular/benchpress/src/reporter/console_reporter.ts b/modules/@angular/benchpress/src/reporter/console_reporter.ts index 832e16835a28e..7867fcddfdb61 100644 --- a/modules/@angular/benchpress/src/reporter/console_reporter.ts +++ b/modules/@angular/benchpress/src/reporter/console_reporter.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, Injectable, OpaqueToken} from '@angular/core'; +import {Inject, Injectable, InjectionToken} from '@angular/core'; import {print} from '../facade/lang'; import {MeasureValues} from '../measure_values'; import {Reporter} from '../reporter'; @@ -20,8 +20,8 @@ import {formatNum, formatStats, sortedProps} from './util'; */ @Injectable() export class ConsoleReporter extends Reporter { - static PRINT = new OpaqueToken('ConsoleReporter.print'); - static COLUMN_WIDTH = new OpaqueToken('ConsoleReporter.columnWidth'); + static PRINT = new InjectionToken('ConsoleReporter.print'); + static COLUMN_WIDTH = new InjectionToken('ConsoleReporter.columnWidth'); static PROVIDERS = [ ConsoleReporter, {provide: ConsoleReporter.COLUMN_WIDTH, useValue: 18}, {provide: ConsoleReporter.PRINT, useValue: print} diff --git a/modules/@angular/benchpress/src/reporter/json_file_reporter.ts b/modules/@angular/benchpress/src/reporter/json_file_reporter.ts index b1d42a14cca39..2a8d0fb62923e 100644 --- a/modules/@angular/benchpress/src/reporter/json_file_reporter.ts +++ b/modules/@angular/benchpress/src/reporter/json_file_reporter.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, Injectable, OpaqueToken} from '@angular/core'; +import {Inject, Injectable, InjectionToken} from '@angular/core'; import {Options} from '../common_options'; import {MeasureValues} from '../measure_values'; @@ -21,7 +21,7 @@ import {formatStats, sortedProps} from './util'; */ @Injectable() export class JsonFileReporter extends Reporter { - static PATH = new OpaqueToken('JsonFileReporter.path'); + static PATH = new InjectionToken('JsonFileReporter.path'); static PROVIDERS = [JsonFileReporter, {provide: JsonFileReporter.PATH, useValue: '.'}]; constructor( diff --git a/modules/@angular/benchpress/src/reporter/multi_reporter.ts b/modules/@angular/benchpress/src/reporter/multi_reporter.ts index fed4bb39b53d2..07b507148ac24 100644 --- a/modules/@angular/benchpress/src/reporter/multi_reporter.ts +++ b/modules/@angular/benchpress/src/reporter/multi_reporter.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injector, OpaqueToken} from '@angular/core'; +import {InjectionToken, Injector} from '@angular/core'; import {MeasureValues} from '../measure_values'; import {Reporter} from '../reporter'; @@ -39,4 +39,4 @@ export class MultiReporter extends Reporter { } } -const _CHILDREN = new OpaqueToken('MultiReporter.children'); +const _CHILDREN = new InjectionToken('MultiReporter.children'); diff --git a/modules/@angular/benchpress/src/sample_description.ts b/modules/@angular/benchpress/src/sample_description.ts index a82e5e1b5eaa8..ccecf159b5754 100644 --- a/modules/@angular/benchpress/src/sample_description.ts +++ b/modules/@angular/benchpress/src/sample_description.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '@angular/core'; +import {InjectionToken} from '@angular/core'; import {Options} from './common_options'; import {Metric} from './metric'; diff --git a/modules/@angular/benchpress/src/validator/regression_slope_validator.ts b/modules/@angular/benchpress/src/validator/regression_slope_validator.ts index 501a7ad7941ea..ec703ca31656b 100644 --- a/modules/@angular/benchpress/src/validator/regression_slope_validator.ts +++ b/modules/@angular/benchpress/src/validator/regression_slope_validator.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, Injectable, OpaqueToken} from '@angular/core'; +import {Inject, Injectable, InjectionToken} from '@angular/core'; import {MeasureValues} from '../measure_values'; import {Statistic} from '../statistic'; @@ -18,8 +18,8 @@ import {Validator} from '../validator'; */ @Injectable() export class RegressionSlopeValidator extends Validator { - static SAMPLE_SIZE = new OpaqueToken('RegressionSlopeValidator.sampleSize'); - static METRIC = new OpaqueToken('RegressionSlopeValidator.metric'); + static SAMPLE_SIZE = new InjectionToken('RegressionSlopeValidator.sampleSize'); + static METRIC = new InjectionToken('RegressionSlopeValidator.metric'); static PROVIDERS = [ RegressionSlopeValidator, {provide: RegressionSlopeValidator.SAMPLE_SIZE, useValue: 10}, {provide: RegressionSlopeValidator.METRIC, useValue: 'scriptTime'} diff --git a/modules/@angular/benchpress/src/validator/size_validator.ts b/modules/@angular/benchpress/src/validator/size_validator.ts index 63dd6ffee1e41..ea892da2ac25b 100644 --- a/modules/@angular/benchpress/src/validator/size_validator.ts +++ b/modules/@angular/benchpress/src/validator/size_validator.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, Injectable, OpaqueToken} from '@angular/core'; +import {Inject, Injectable, InjectionToken} from '@angular/core'; import {MeasureValues} from '../measure_values'; import {Validator} from '../validator'; @@ -16,7 +16,7 @@ import {Validator} from '../validator'; */ @Injectable() export class SizeValidator extends Validator { - static SAMPLE_SIZE = new OpaqueToken('SizeValidator.sampleSize'); + static SAMPLE_SIZE = new InjectionToken('SizeValidator.sampleSize'); static PROVIDERS = [SizeValidator, {provide: SizeValidator.SAMPLE_SIZE, useValue: 10}]; constructor(@Inject(SizeValidator.SAMPLE_SIZE) private _sampleSize: number) { super(); } diff --git a/modules/@angular/benchpress/src/web_driver_extension.ts b/modules/@angular/benchpress/src/web_driver_extension.ts index 4979f1e773c92..ae07ab9aa9555 100644 --- a/modules/@angular/benchpress/src/web_driver_extension.ts +++ b/modules/@angular/benchpress/src/web_driver_extension.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injector, OpaqueToken} from '@angular/core'; +import {InjectionToken, Injector} from '@angular/core'; import {Options} from './common_options'; @@ -101,4 +101,4 @@ export class PerfLogFeatures { } } -const _CHILDREN = new OpaqueToken('WebDriverExtension.children'); +const _CHILDREN = new InjectionToken('WebDriverExtension.children'); diff --git a/modules/@angular/common/src/location/location_strategy.ts b/modules/@angular/common/src/location/location_strategy.ts index afba50d84f7e1..d5b19979b1510 100644 --- a/modules/@angular/common/src/location/location_strategy.ts +++ b/modules/@angular/common/src/location/location_strategy.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '@angular/core'; +import {InjectionToken} from '@angular/core'; import {LocationChangeListener} from './platform_location'; /** @@ -61,4 +61,4 @@ export abstract class LocationStrategy { * * @stable */ -export const APP_BASE_HREF: OpaqueToken = new OpaqueToken('appBaseHref'); +export const APP_BASE_HREF = new InjectionToken('appBaseHref'); diff --git a/modules/@angular/common/test/directives/ng_component_outlet_spec.ts b/modules/@angular/common/test/directives/ng_component_outlet_spec.ts index 58e91d63171a1..ff78514614cb4 100644 --- a/modules/@angular/common/test/directives/ng_component_outlet_spec.ts +++ b/modules/@angular/common/test/directives/ng_component_outlet_spec.ts @@ -8,7 +8,7 @@ import {CommonModule} from '@angular/common'; import {NgComponentOutlet} from '@angular/common/src/directives/ng_component_outlet'; -import {Component, ComponentRef, Inject, Injector, NO_ERRORS_SCHEMA, NgModule, OpaqueToken, Optional, Provider, QueryList, ReflectiveInjector, TemplateRef, Type, ViewChild, ViewChildren, ViewContainerRef} from '@angular/core'; +import {Component, ComponentRef, Inject, InjectionToken, Injector, NO_ERRORS_SCHEMA, NgModule, Optional, Provider, QueryList, ReflectiveInjector, TemplateRef, Type, ViewChild, ViewChildren, ViewContainerRef} from '@angular/core'; import {TestBed, async} from '@angular/core/testing'; import {expect} from '@angular/platform-browser/testing/matchers'; @@ -146,7 +146,7 @@ export function main() { }); } -const TEST_TOKEN = new OpaqueToken('TestToken'); +const TEST_TOKEN = new InjectionToken('TestToken'); @Component({selector: 'injected-component', template: 'foo'}) class InjectedComponent { constructor(@Optional() @Inject(TEST_TOKEN) public testToken: any) {} diff --git a/modules/@angular/compiler-cli/integrationtest/src/entry_components.ts b/modules/@angular/compiler-cli/integrationtest/src/entry_components.ts index 41e2005c88558..f969dd25d2941 100644 --- a/modules/@angular/compiler-cli/integrationtest/src/entry_components.ts +++ b/modules/@angular/compiler-cli/integrationtest/src/entry_components.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ANALYZE_FOR_ENTRY_COMPONENTS, Component, ComponentFactoryResolver, Inject, OpaqueToken} from '@angular/core'; +import {ANALYZE_FOR_ENTRY_COMPONENTS, Component, ComponentFactoryResolver, Inject, InjectionToken} from '@angular/core'; import {BasicComp} from './basic'; @@ -15,7 +15,7 @@ export class CompWithEntryComponents { constructor(public cfr: ComponentFactoryResolver) {} } -export const SOME_TOKEN = new OpaqueToken('someToken'); +export const SOME_TOKEN = new InjectionToken('someToken'); export function provideValueWithEntryComponents(value: any) { return [ diff --git a/modules/@angular/compiler-cli/integrationtest/src/features.ts b/modules/@angular/compiler-cli/integrationtest/src/features.ts index 1d893d219f473..e6196dbd94bf7 100644 --- a/modules/@angular/compiler-cli/integrationtest/src/features.ts +++ b/modules/@angular/compiler-cli/integrationtest/src/features.ts @@ -7,21 +7,21 @@ */ import * as common from '@angular/common'; -import {CUSTOM_ELEMENTS_SCHEMA, Component, Directive, EventEmitter, Inject, NgModule, OpaqueToken, Output} from '@angular/core'; +import {CUSTOM_ELEMENTS_SCHEMA, Component, Directive, EventEmitter, Inject, InjectionToken, NgModule, Output} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import {wrapInArray} from './funcs'; -export const SOME_OPAQUE_TOKEN = new OpaqueToken('opaqueToken'); +export const SOME_INJECTON_TOKEN = new InjectionToken('injectionToken'); @Component({ selector: 'comp-providers', template: '', providers: [ {provide: 'strToken', useValue: 'strValue'}, - {provide: SOME_OPAQUE_TOKEN, useValue: 10}, + {provide: SOME_INJECTON_TOKEN, useValue: 10}, {provide: 'reference', useValue: common.NgIf}, - {provide: 'complexToken', useValue: {a: 1, b: ['test', SOME_OPAQUE_TOKEN]}}, + {provide: 'complexToken', useValue: {a: 1, b: ['test', SOME_INJECTON_TOKEN]}}, ] }) export class CompWithProviders { diff --git a/modules/@angular/compiler-cli/integrationtest/src/module_fixtures.ts b/modules/@angular/compiler-cli/integrationtest/src/module_fixtures.ts index b38de7daf83f9..febffef8144d0 100644 --- a/modules/@angular/compiler-cli/integrationtest/src/module_fixtures.ts +++ b/modules/@angular/compiler-cli/integrationtest/src/module_fixtures.ts @@ -7,7 +7,7 @@ */ import {LowerCasePipe, NgIf} from '@angular/common'; -import {ANALYZE_FOR_ENTRY_COMPONENTS, Component, ComponentFactoryResolver, Directive, Inject, Injectable, Input, ModuleWithProviders, NgModule, OpaqueToken, Pipe} from '@angular/core'; +import {ANALYZE_FOR_ENTRY_COMPONENTS, Component, ComponentFactoryResolver, Directive, Inject, Injectable, InjectionToken, Input, ModuleWithProviders, NgModule, Pipe} from '@angular/core'; @Injectable() export class SomeService { @@ -48,7 +48,7 @@ export class CompUsingRootModuleDirectiveAndPipe { export class CompUsingLibModuleDirectiveAndPipe { } -export const SOME_TOKEN = new OpaqueToken('someToken'); +export const SOME_TOKEN = new InjectionToken('someToken'); export function provideValueWithEntryComponents(value: any) { return [ diff --git a/modules/@angular/compiler/src/aot/static_reflector.ts b/modules/@angular/compiler/src/aot/static_reflector.ts index 4858068fe1c42..4844e245f049f 100644 --- a/modules/@angular/compiler/src/aot/static_reflector.ts +++ b/modules/@angular/compiler/src/aot/static_reflector.ts @@ -17,7 +17,8 @@ const ANGULAR_IMPORT_LOCATIONS = { coreDecorators: '@angular/core/src/metadata', diDecorators: '@angular/core/src/di/metadata', diMetadata: '@angular/core/src/di/metadata', - diOpaqueToken: '@angular/core/src/di/opaque_token', + diInjectionToken: '@angular/core/src/di/injection_token', + diOpaqueToken: '@angular/core/src/di/injection_token', animationMetadata: '@angular/core/src/animation/metadata', provider: '@angular/core/src/di/provider' }; @@ -34,6 +35,7 @@ export class StaticReflector implements ReflectorReader { private parameterCache = new Map(); private methodCache = new Map(); private conversionMap = new Map any>(); + private injectionToken: StaticSymbol; private opaqueToken: StaticSymbol; constructor( @@ -229,9 +231,10 @@ export class StaticReflector implements ReflectorReader { } private initializeConversionMap(): void { - const {coreDecorators, diDecorators, diMetadata, diOpaqueToken, animationMetadata, provider} = - ANGULAR_IMPORT_LOCATIONS; - this.opaqueToken = this.findDeclaration(diOpaqueToken, 'OpaqueToken'); + const {coreDecorators, diDecorators, diMetadata, diInjectionToken, + diOpaqueToken, animationMetadata, provider} = ANGULAR_IMPORT_LOCATIONS; + this.injectionToken = this.findDeclaration(diInjectionToken, 'InjectionToken'); + this.opaqueToken = this.findDeclaration(diInjectionToken, 'OpaqueToken'); this._registerDecoratorOrConstructor(this.findDeclaration(diDecorators, 'Host'), Host); this._registerDecoratorOrConstructor( @@ -382,7 +385,8 @@ export class StaticReflector implements ReflectorReader { } if (expression instanceof StaticSymbol) { // Stop simplification at builtin symbols - if (expression === self.opaqueToken || self.conversionMap.has(expression)) { + if (expression === self.injectionToken || expression === self.opaqueToken || + self.conversionMap.has(expression)) { return expression; } else { const staticSymbol = expression; @@ -506,9 +510,9 @@ export class StaticReflector implements ReflectorReader { // Determine if the function is a built-in conversion staticSymbol = simplifyInContext(context, expression['expression'], depth + 1); if (staticSymbol instanceof StaticSymbol) { - if (staticSymbol === self.opaqueToken) { - // if somebody calls new OpaqueToken, don't create an OpaqueToken, - // but rather return the symbol to which the OpaqueToken is assigned to. + if (staticSymbol === self.injectionToken || staticSymbol === self.opaqueToken) { + // if somebody calls new InjectionToken, don't create an InjectionToken, + // but rather return the symbol to which the InjectionToken is assigned to. return context; } const argExpressions: any[] = expression['arguments'] || []; @@ -674,4 +678,4 @@ function positionalError(message: string, fileName: string, line: number, column (result as any).line = line; (result as any).column = column; return result; -} \ No newline at end of file +} diff --git a/modules/@angular/compiler/src/jit/compiler_factory.ts b/modules/@angular/compiler/src/jit/compiler_factory.ts index 2f8be8e3d05c6..40a05ff5ac121 100644 --- a/modules/@angular/compiler/src/jit/compiler_factory.ts +++ b/modules/@angular/compiler/src/jit/compiler_factory.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {COMPILER_OPTIONS, Compiler, CompilerFactory, CompilerOptions, Inject, OpaqueToken, Optional, PLATFORM_INITIALIZER, PlatformRef, Provider, ReflectiveInjector, TRANSLATIONS, TRANSLATIONS_FORMAT, Type, ViewEncapsulation, createPlatformFactory, isDevMode, platformCore} from '@angular/core'; +import {COMPILER_OPTIONS, Compiler, CompilerFactory, CompilerOptions, Inject, InjectionToken, Optional, PLATFORM_INITIALIZER, PlatformRef, Provider, ReflectiveInjector, TRANSLATIONS, TRANSLATIONS_FORMAT, Type, ViewEncapsulation, createPlatformFactory, isDevMode, platformCore} from '@angular/core'; import {AnimationParser} from '../animation/animation_parser'; import {CompilerConfig} from '../config'; @@ -40,7 +40,7 @@ const _NO_RESOURCE_LOADER: ResourceLoader = { `No ResourceLoader implementation has been provided. Can't read the url "${url}"`);} }; -const baseHtmlParser = new OpaqueToken('HtmlParser'); +const baseHtmlParser = new InjectionToken('HtmlParser'); /** * A set of providers that provide `JitCompiler` and its dependencies to use for diff --git a/modules/@angular/compiler/src/metadata_resolver.ts b/modules/@angular/compiler/src/metadata_resolver.ts index 6270315039bdc..e7ccd1df97cbd 100644 --- a/modules/@angular/compiler/src/metadata_resolver.ts +++ b/modules/@angular/compiler/src/metadata_resolver.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, Attribute, ChangeDetectionStrategy, Component, ComponentFactory, Directive, Host, Inject, Injectable, ModuleWithProviders, OpaqueToken, Optional, Provider, Query, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef} from '@angular/core'; +import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, Attribute, ChangeDetectionStrategy, Component, ComponentFactory, Directive, Host, Inject, Injectable, InjectionToken, ModuleWithProviders, Optional, Provider, Query, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef} from '@angular/core'; import {StaticSymbol, StaticSymbolCache} from './aot/static_symbol'; import {ngfactoryFilePath} from './aot/util'; @@ -27,7 +27,7 @@ import {getUrlScheme} from './url_resolver'; import {MODULE_SUFFIX, SyntaxError, ValueTransformer, visitValue} from './util'; export type ErrorCollector = (error: any, type?: any) => void; -export const ERROR_COLLECTOR_TOKEN = new OpaqueToken('ErrorCollector'); +export const ERROR_COLLECTOR_TOKEN = new InjectionToken('ErrorCollector'); // Design notes: // - don't lazily create metadata: diff --git a/modules/@angular/compiler/src/template_parser/template_parser.ts b/modules/@angular/compiler/src/template_parser/template_parser.ts index 493b371bd6029..f5b8350467385 100644 --- a/modules/@angular/compiler/src/template_parser/template_parser.ts +++ b/modules/@angular/compiler/src/template_parser/template_parser.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, OpaqueToken, Optional, SchemaMetadata} from '@angular/core'; +import {Inject, InjectionToken, Optional, SchemaMetadata} from '@angular/core'; import {CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeSummary, CompileTemplateSummary, CompileTokenMetadata, CompileTypeMetadata, identifierName} from '../compile_metadata'; import {Parser} from '../expression_parser/parser'; import {isPresent} from '../facade/lang'; @@ -67,7 +67,7 @@ const TEXT_CSS_SELECTOR = CssSelector.parse('*')[0]; * * This is currently an internal-only feature and not meant for general use. */ -export const TEMPLATE_TRANSFORMS = new OpaqueToken('TemplateTransforms'); +export const TEMPLATE_TRANSFORMS = new InjectionToken('TemplateTransforms'); export class TemplateParseError extends ParseError { constructor(message: string, span: ParseSourceSpan, level: ParseErrorLevel) { diff --git a/modules/@angular/compiler/src/url_resolver.ts b/modules/@angular/compiler/src/url_resolver.ts index 8f6b47779fb19..e800ec813713e 100644 --- a/modules/@angular/compiler/src/url_resolver.ts +++ b/modules/@angular/compiler/src/url_resolver.ts @@ -6,12 +6,13 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, PACKAGE_ROOT_URL} from '@angular/core'; +import {Inject, InjectionToken, PACKAGE_ROOT_URL} from '@angular/core'; import {isBlank, isPresent} from './facade/lang'; import {CompilerInjectable} from './injectable'; + /** * Create a {@link UrlResolver} with no package prefix. */ diff --git a/modules/@angular/core/src/application_init.ts b/modules/@angular/core/src/application_init.ts index 45657ce9db68e..e73c649f5c8e5 100644 --- a/modules/@angular/core/src/application_init.ts +++ b/modules/@angular/core/src/application_init.ts @@ -8,14 +8,14 @@ import {isPromise} from '../src/util/lang'; -import {Inject, Injectable, OpaqueToken, Optional} from './di'; +import {Inject, Injectable, InjectionToken, Optional} from './di'; /** * A function that will be executed when an application is initialized. * @experimental */ -export const APP_INITIALIZER: any = new OpaqueToken('Application Initializer'); +export const APP_INITIALIZER = new InjectionToken void>>('Application Initializer'); /** * A class that reflects the state of running {@link APP_INITIALIZER}s. diff --git a/modules/@angular/core/src/application_ref.ts b/modules/@angular/core/src/application_ref.ts index 4e8a2aff85267..2e3dfe1446f9c 100644 --- a/modules/@angular/core/src/application_ref.ts +++ b/modules/@angular/core/src/application_ref.ts @@ -16,7 +16,7 @@ import {ApplicationInitStatus} from './application_init'; import {APP_BOOTSTRAP_LISTENER, PLATFORM_INITIALIZER} from './application_tokens'; import {ChangeDetectorRef} from './change_detection/change_detector_ref'; import {Console} from './console'; -import {Injectable, Injector, OpaqueToken, Optional, Provider, ReflectiveInjector} from './di'; +import {Injectable, InjectionToken, Injector, Optional, Provider, ReflectiveInjector} from './di'; import {CompilerFactory, CompilerOptions} from './linker/compiler'; import {ComponentFactory, ComponentRef} from './linker/component_factory'; import {ComponentFactoryResolver} from './linker/component_factory_resolver'; @@ -83,7 +83,7 @@ export function createPlatform(injector: Injector): PlatformRef { 'There can be only one platform. Destroy the previous one to create a new one.'); } _platform = injector.get(PlatformRef); - const inits: Function[] = injector.get(PLATFORM_INITIALIZER, null); + const inits = injector.get(PLATFORM_INITIALIZER, null); if (inits) inits.forEach(init => init()); return _platform; } @@ -96,7 +96,7 @@ export function createPlatform(injector: Injector): PlatformRef { export function createPlatformFactory( parentPlatformFactory: (extraProviders?: Provider[]) => PlatformRef, name: string, providers: Provider[] = []): (extraProviders?: Provider[]) => PlatformRef { - const marker = new OpaqueToken(`Platform: ${name}`); + const marker = new InjectionToken(`Platform: ${name}`); return (extraProviders: Provider[] = []) => { if (!getPlatform()) { if (parentPlatformFactory) { @@ -413,7 +413,7 @@ export class ApplicationRef_ extends ApplicationRef { /** @internal */ static _tickScope: WtfScopeFn = wtfCreateScope('ApplicationRef#tick()'); - private _bootstrapListeners: Function[] = []; + private _bootstrapListeners: ((compRef: ComponentRef) => void)[] = []; private _rootComponents: ComponentRef[] = []; private _rootComponentTypes: Type[] = []; private _views: AppView[] = []; @@ -480,8 +480,7 @@ export class ApplicationRef_ extends ApplicationRef { this._rootComponents.push(componentRef); // Get the listeners lazily to prevent DI cycles. const listeners = - <((compRef: ComponentRef) => void)[]>this._injector.get(APP_BOOTSTRAP_LISTENER, []) - .concat(this._bootstrapListeners); + this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners); listeners.forEach((listener) => listener(componentRef)); } diff --git a/modules/@angular/core/src/application_tokens.ts b/modules/@angular/core/src/application_tokens.ts index b33e364f90bd0..31c598513578c 100644 --- a/modules/@angular/core/src/application_tokens.ts +++ b/modules/@angular/core/src/application_tokens.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from './di'; +import {InjectionToken} from './di'; +import {ComponentRef} from './linker/component_factory'; /** @@ -19,7 +20,7 @@ import {OpaqueToken} from './di'; * using this token. * @experimental */ -export const APP_ID: any = new OpaqueToken('AppId'); +export const APP_ID = new InjectionToken('AppId'); export function _appIdRandomProviderFactory() { return `${_randomChar()}${_randomChar()}${_randomChar()}`; @@ -43,7 +44,7 @@ function _randomChar(): string { * A function that will be executed when a platform is initialized. * @experimental */ -export const PLATFORM_INITIALIZER: any = new OpaqueToken('Platform Initializer'); +export const PLATFORM_INITIALIZER = new InjectionToken void>>('Platform Initializer'); /** * All callbacks provided via this token will be called for every component that is bootstrapped. @@ -53,10 +54,11 @@ export const PLATFORM_INITIALIZER: any = new OpaqueToken('Platform Initializer') * * @experimental */ -export const APP_BOOTSTRAP_LISTENER = new OpaqueToken('appBootstrapListener'); +export const APP_BOOTSTRAP_LISTENER = + new InjectionToken) => void>>('appBootstrapListener'); /** * A token which indicates the root directory of the application * @experimental */ -export const PACKAGE_ROOT_URL: any = new OpaqueToken('Application Packages Root URL'); +export const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL'); diff --git a/modules/@angular/core/src/di.ts b/modules/@angular/core/src/di.ts index cc05afff72c98..cbfcbaf62d7a8 100644 --- a/modules/@angular/core/src/di.ts +++ b/modules/@angular/core/src/di.ts @@ -21,4 +21,4 @@ export {ReflectiveInjector} from './di/reflective_injector'; export {Provider, TypeProvider, ValueProvider, ClassProvider, ExistingProvider, FactoryProvider} from './di/provider'; export {ResolvedReflectiveFactory, ResolvedReflectiveProvider} from './di/reflective_provider'; export {ReflectiveKey} from './di/reflective_key'; -export {OpaqueToken} from './di/opaque_token'; +export {InjectionToken, OpaqueToken} from './di/injection_token'; diff --git a/modules/@angular/core/src/di/injection_token.ts b/modules/@angular/core/src/di/injection_token.ts index 40ef480138e25..d75b9b661d684 100644 --- a/modules/@angular/core/src/di/injection_token.ts +++ b/modules/@angular/core/src/di/injection_token.ts @@ -26,10 +26,42 @@ * * Using an `OpaqueToken` is preferable to using an `Object` as tokens because it provides better * error messages. - * @stable + * @deprecated since v4.0.0 because it does not support type information, use `InjectionToken` + * instead. */ export class OpaqueToken { - constructor(private _desc: string) {} + constructor(protected _desc: string) {} toString(): string { return `Token ${this._desc}`; } } + +/** + * Creates a token that can be used in a DI Provider. + * + * Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a + * runtime representation) such as when injecting an interface, callable type, array or + * parametrized type. + * + * `InjectionToken` is parametrize on `T` which is the type of object which will be returned by the + * `Injector`. This provides additional level of type safety. + * + * ``` + * interface MyInterface {...} + * var myInterface = injector.get(new InjectionToken('SomeToken')); + * // myInterface is inferred to be MyInterface. + * ``` + * + * ### Example + * + * {@example core/di/ts/injector_spec.ts region='Injector'} + * + * @stable + */ +export class InjectionToken extends OpaqueToken { + // This unused property is needed here so that TS can differentiate InjectionToken from + // OpaqueToken since otherwise they would have the same shape and be treated as equivalent. + private _differentiate_from_OpaqueToken_structurally: any; + constructor(desc: string) { super(desc); } + + toString(): string { return `InjectionToken ${this._desc}`; } +} diff --git a/modules/@angular/core/src/di/injector.ts b/modules/@angular/core/src/di/injector.ts index 3af3b5fa975d3..1b7eeb61f5406 100644 --- a/modules/@angular/core/src/di/injector.ts +++ b/modules/@angular/core/src/di/injector.ts @@ -8,6 +8,9 @@ import {unimplemented} from '../facade/errors'; import {stringify} from '../facade/lang'; +import {Type} from '../type'; + +import {InjectionToken} from './injection_token'; const _THROW_IF_NOT_FOUND = new Object(); export const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND; @@ -52,5 +55,10 @@ export abstract class Injector { * Injector.THROW_IF_NOT_FOUND is given * - Returns the `notFoundValue` otherwise */ + get(token: Type|InjectionToken, notFoundValue?: T): T; + /** + * @deprecated from v4.0.0 use Type or InjectToken + */ + get(token: any, notFoundValue?: any): any; get(token: any, notFoundValue?: any): any { return unimplemented(); } } diff --git a/modules/@angular/core/src/di/provider.ts b/modules/@angular/core/src/di/provider.ts index d22c829f4f991..18f379887a175 100644 --- a/modules/@angular/core/src/di/provider.ts +++ b/modules/@angular/core/src/di/provider.ts @@ -52,7 +52,7 @@ export interface TypeProvider extends Type {} */ export interface ValueProvider { /** - * An injection token. (Typically an instance of `Type` or `OpaqueToken`, but can be `any`). + * An injection token. (Typically an instance of `Type` or `InjectionToken`, but can be `any`). */ provide: any; @@ -96,7 +96,7 @@ export interface ValueProvider { */ export interface ClassProvider { /** - * An injection token. (Typically an instance of `Type` or `OpaqueToken`, but can be `any`). + * An injection token. (Typically an instance of `Type` or `InjectionToken`, but can be `any`). */ provide: any; @@ -134,7 +134,7 @@ export interface ClassProvider { */ export interface ExistingProvider { /** - * An injection token. (Typically an instance of `Type` or `OpaqueToken`, but can be `any`). + * An injection token. (Typically an instance of `Type` or `InjectionToken`, but can be `any`). */ provide: any; @@ -178,7 +178,7 @@ export interface ExistingProvider { */ export interface FactoryProvider { /** - * An injection token. (Typically an instance of `Type` or `OpaqueToken`, but can be `any`). + * An injection token. (Typically an instance of `Type` or `InjectionToken`, but can be `any`). */ provide: any; diff --git a/modules/@angular/core/src/i18n/tokens.ts b/modules/@angular/core/src/i18n/tokens.ts index 0eba286a091ff..e6735c03cb967 100644 --- a/modules/@angular/core/src/i18n/tokens.ts +++ b/modules/@angular/core/src/i18n/tokens.ts @@ -6,19 +6,19 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '../di/opaque_token'; +import {InjectionToken} from '../di/injection_token'; /** * @experimental i18n support is experimental. */ -export const LOCALE_ID = new OpaqueToken('LocaleId'); +export const LOCALE_ID = new InjectionToken('LocaleId'); /** * @experimental i18n support is experimental. */ -export const TRANSLATIONS = new OpaqueToken('Translations'); +export const TRANSLATIONS = new InjectionToken('Translations'); /** * @experimental i18n support is experimental. */ -export const TRANSLATIONS_FORMAT = new OpaqueToken('TranslationsFormat'); +export const TRANSLATIONS_FORMAT = new InjectionToken('TranslationsFormat'); diff --git a/modules/@angular/core/src/linker/compiler.ts b/modules/@angular/core/src/linker/compiler.ts index a635c119d98e9..c210078535af5 100644 --- a/modules/@angular/core/src/linker/compiler.ts +++ b/modules/@angular/core/src/linker/compiler.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injectable, OpaqueToken} from '../di'; +import {Injectable, InjectionToken} from '../di'; import {BaseError} from '../facade/errors'; import {stringify} from '../facade/lang'; import {ViewEncapsulation} from '../metadata'; @@ -119,7 +119,7 @@ export type CompilerOptions = { * * @experimental */ -export const COMPILER_OPTIONS = new OpaqueToken('compilerOptions'); +export const COMPILER_OPTIONS = new InjectionToken('compilerOptions'); /** * A factory for creating a Compiler diff --git a/modules/@angular/core/src/metadata/di.ts b/modules/@angular/core/src/metadata/di.ts index 61647c95dc54c..013d4568d1f0a 100644 --- a/modules/@angular/core/src/metadata/di.ts +++ b/modules/@angular/core/src/metadata/di.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '../di/opaque_token'; +import {InjectionToken} from '../di/injection_token'; import {Type} from '../type'; import {makeParamDecorator, makePropDecorator} from '../util/decorators'; @@ -44,7 +44,7 @@ import {makeParamDecorator, makePropDecorator} from '../util/decorators'; * * @experimental */ -export const ANALYZE_FOR_ENTRY_COMPONENTS = new OpaqueToken('AnalyzeForEntryComponents'); +export const ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken('AnalyzeForEntryComponents'); /** * Type of the Attribute decorator / constructor function. diff --git a/modules/@angular/core/test/linker/integration_spec.ts b/modules/@angular/core/test/linker/integration_spec.ts index d6b9b7bdcab30..7a39c769fc266 100644 --- a/modules/@angular/core/test/linker/integration_spec.ts +++ b/modules/@angular/core/test/linker/integration_spec.ts @@ -7,7 +7,7 @@ */ import {CommonModule} from '@angular/common'; -import {ComponentFactory, Host, Inject, Injectable, Injector, NO_ERRORS_SCHEMA, NgModule, OnDestroy, OpaqueToken, ReflectiveInjector, SkipSelf} from '@angular/core'; +import {ComponentFactory, Host, Inject, Injectable, InjectionToken, Injector, NO_ERRORS_SCHEMA, NgModule, OnDestroy, ReflectiveInjector, SkipSelf} from '@angular/core'; import {ChangeDetectionStrategy, ChangeDetectorRef, PipeTransform} from '@angular/core/src/change_detection/change_detection'; import {ComponentFactoryResolver} from '@angular/core/src/linker/component_factory_resolver'; import {ElementRef} from '@angular/core/src/linker/element_ref'; @@ -25,7 +25,7 @@ import {expect} from '@angular/platform-browser/testing/matchers'; import {EventEmitter} from '../../src/facade/async'; import {isBlank, isPresent, stringify} from '../../src/facade/lang'; -const ANCHOR_ELEMENT = new OpaqueToken('AnchorElement'); +const ANCHOR_ELEMENT = new InjectionToken('AnchorElement'); export function main() { describe('jit', () => { declareTests({useJit: true}); }); diff --git a/modules/@angular/core/test/linker/ng_module_integration_spec.ts b/modules/@angular/core/test/linker/ng_module_integration_spec.ts index 126d64fbadf56..55bbb298ae21e 100644 --- a/modules/@angular/core/test/linker/ng_module_integration_spec.ts +++ b/modules/@angular/core/test/linker/ng_module_integration_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ANALYZE_FOR_ENTRY_COMPONENTS, CUSTOM_ELEMENTS_SCHEMA, Compiler, Component, ComponentFactoryResolver, Directive, HostBinding, Inject, Injectable, Injector, Input, NgModule, NgModuleRef, Optional, Pipe, Provider, Self, Type, forwardRef, getModuleFactory} from '@angular/core'; +import {ANALYZE_FOR_ENTRY_COMPONENTS, CUSTOM_ELEMENTS_SCHEMA, Compiler, Component, ComponentFactoryResolver, Directive, HostBinding, Inject, Injectable, InjectionToken, Injector, Input, NgModule, NgModuleRef, Optional, Pipe, Provider, Self, Type, forwardRef, getModuleFactory} from '@angular/core'; import {Console} from '@angular/core/src/console'; import {ComponentFixture, TestBed, inject} from '@angular/core/testing'; import {expect} from '@angular/platform-browser/testing/matchers'; @@ -30,6 +30,7 @@ class Dashboard { class TurboEngine extends Engine {} +const CARS = new InjectionToken('Cars'); @Injectable() class Car { engine: Engine; @@ -692,11 +693,11 @@ function declareTests({useJit}: {useJit: boolean}) { it('should support multiProviders', () => { const injector = createInjector([ - Engine, {provide: Car, useClass: SportsCar, multi: true}, - {provide: Car, useClass: CarWithOptionalEngine, multi: true} + Engine, {provide: CARS, useClass: SportsCar, multi: true}, + {provide: CARS, useClass: CarWithOptionalEngine, multi: true} ]); - const cars = injector.get(Car); + const cars = injector.get(CARS); expect(cars.length).toEqual(2); expect(cars[0]).toBeAnInstanceOf(SportsCar); expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine); @@ -704,9 +705,9 @@ function declareTests({useJit}: {useJit: boolean}) { it('should support multiProviders that are created using useExisting', () => { const injector = createInjector( - [Engine, SportsCar, {provide: Car, useExisting: SportsCar, multi: true}]); + [Engine, SportsCar, {provide: CARS, useExisting: SportsCar, multi: true}]); - const cars = injector.get(Car); + const cars = injector.get(CARS); expect(cars.length).toEqual(1); expect(cars[0]).toBe(injector.get(SportsCar)); }); diff --git a/modules/@angular/core/test/linker/regression_integration_spec.ts b/modules/@angular/core/test/linker/regression_integration_spec.ts index fea9b6df76761..f5be23e03d3d2 100644 --- a/modules/@angular/core/test/linker/regression_integration_spec.ts +++ b/modules/@angular/core/test/linker/regression_integration_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ANALYZE_FOR_ENTRY_COMPONENTS, Component, Injector, OpaqueToken, Pipe, PipeTransform, Provider} from '@angular/core'; +import {ANALYZE_FOR_ENTRY_COMPONENTS, Component, InjectionToken, Injector, Pipe, PipeTransform, Provider} from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {expect} from '@angular/platform-browser/testing/matchers'; @@ -104,8 +104,8 @@ function declareTests({useJit}: {useJit: boolean}) { return TestBed.createComponent(MyComp1).componentInstance.injector; } - it('should support providers with an OpaqueToken that contains a `.` in the name', () => { - const token = new OpaqueToken('a.b'); + it('should support providers with an InjectionToken that contains a `.` in the name', () => { + const token = new InjectionToken('a.b'); const tokenValue = 1; const injector = createInjector([{provide: token, useValue: tokenValue}]); expect(injector.get(token)).toEqual(tokenValue); @@ -127,9 +127,9 @@ function declareTests({useJit}: {useJit: boolean}) { expect(injector.get(token)).toEqual(tokenValue); }); - it('should support providers with an OpaqueToken that has a StringMap as value', () => { - const token1 = new OpaqueToken('someToken'); - const token2 = new OpaqueToken('someToken'); + it('should support providers with an InjectionToken that has a StringMap as value', () => { + const token1 = new InjectionToken('someToken'); + const token2 = new InjectionToken('someToken'); const tokenValue1 = {'a': 1}; const tokenValue2 = {'a': 1}; const injector = createInjector( diff --git a/modules/@angular/core/testing/test_bed.ts b/modules/@angular/core/testing/test_bed.ts index 6436162194174..9e9e29c110215 100644 --- a/modules/@angular/core/testing/test_bed.ts +++ b/modules/@angular/core/testing/test_bed.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {CompilerOptions, Component, Directive, Injector, ModuleWithComponentFactories, NgModule, NgModuleRef, NgZone, OpaqueToken, Pipe, PlatformRef, Provider, ReflectiveInjector, SchemaMetadata, Type} from '@angular/core'; +import {CompilerOptions, Component, Directive, InjectionToken, Injector, ModuleWithComponentFactories, NgModule, NgModuleRef, NgZone, Pipe, PlatformRef, Provider, ReflectiveInjector, SchemaMetadata, Type} from '@angular/core'; import {AsyncTestCompleter} from './async_test_completer'; import {ComponentFixture} from './component_fixture'; @@ -30,12 +30,13 @@ let _nextRootElementId = 0; /** * @experimental */ -export const ComponentFixtureAutoDetect = new OpaqueToken('ComponentFixtureAutoDetect'); +export const ComponentFixtureAutoDetect = + new InjectionToken('ComponentFixtureAutoDetect'); /** * @experimental */ -export const ComponentFixtureNoNgZone = new OpaqueToken('ComponentFixtureNoNgZone'); +export const ComponentFixtureNoNgZone = new InjectionToken('ComponentFixtureNoNgZone'); /** * @experimental diff --git a/modules/@angular/examples/core/di/ts/injector_spec.ts b/modules/@angular/examples/core/di/ts/injector_spec.ts index 9b0a327705693..e04d2434f0b86 100644 --- a/modules/@angular/examples/core/di/ts/injector_spec.ts +++ b/modules/@angular/examples/core/di/ts/injector_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injector, ReflectiveInjector} from '@angular/core'; +import {InjectionToken, Injector, ReflectiveInjector} from '@angular/core'; export function main() { describe('injector metadata examples', () => { @@ -25,7 +25,17 @@ export function main() { const injector = ReflectiveInjector.resolveAndCreate([]); expect(injector.get(Injector)).toBe(injector); // #enddocregion + }); + it('should infer type', () => { + // #docregion InjectionToken + const BASE_URL = new InjectionToken('BaseUrl'); + const injector = + ReflectiveInjector.resolveAndCreate([{provide: BASE_URL, useValue: 'http://localhost'}]); + const url = injector.get(BASE_URL); + // here `url` is inferred to be `string` because `BASE_URL` is `InjectionToken`. + expect(url).toBe('http://localhost'); + // #enddocregion }); }); } diff --git a/modules/@angular/examples/core/di/ts/provider_spec.ts b/modules/@angular/examples/core/di/ts/provider_spec.ts index a2911d3d9ec0e..2e964799e3f26 100644 --- a/modules/@angular/examples/core/di/ts/provider_spec.ts +++ b/modules/@angular/examples/core/di/ts/provider_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, Injectable, OpaqueToken, Optional, ReflectiveInjector} from '@angular/core'; +import {Inject, Injectable, InjectionToken, Optional, ReflectiveInjector} from '@angular/core'; export function main() { describe('Provider examples', () => { @@ -113,8 +113,8 @@ export function main() { describe('FactoryProvider', () => { it('works', () => { // #docregion FactoryProvider - const Location = new OpaqueToken('location'); - const Hash = new OpaqueToken('hash'); + const Location = new InjectionToken('location'); + const Hash = new InjectionToken('hash'); const injector = ReflectiveInjector.resolveAndCreate([ {provide: Location, useValue: 'http://angular.io/#someLocation'}, { @@ -130,8 +130,8 @@ export function main() { it('supports optional dependencies', () => { // #docregion FactoryProviderOptionalDeps - const Location = new OpaqueToken('location'); - const Hash = new OpaqueToken('hash'); + const Location = new InjectionToken('location'); + const Hash = new InjectionToken('hash'); const injector = ReflectiveInjector.resolveAndCreate([{ provide: Hash, diff --git a/modules/@angular/forms/src/directives/control_value_accessor.ts b/modules/@angular/forms/src/directives/control_value_accessor.ts index d0c9c13942cff..41bf922327c3b 100644 --- a/modules/@angular/forms/src/directives/control_value_accessor.ts +++ b/modules/@angular/forms/src/directives/control_value_accessor.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '@angular/core'; +import {InjectionToken} from '@angular/core'; /** * A bridge between a control and a native element. @@ -49,4 +49,4 @@ export interface ControlValueAccessor { * See {@link DefaultValueAccessor} for how to implement one. * @stable */ -export const NG_VALUE_ACCESSOR: OpaqueToken = new OpaqueToken('NgValueAccessor'); +export const NG_VALUE_ACCESSOR = new InjectionToken('NgValueAccessor'); diff --git a/modules/@angular/forms/src/directives/shared.ts b/modules/@angular/forms/src/directives/shared.ts index a47cbf1cb4f19..4b3a8c4eebc0d 100644 --- a/modules/@angular/forms/src/directives/shared.ts +++ b/modules/@angular/forms/src/directives/shared.ts @@ -116,12 +116,11 @@ function _throwError(dir: AbstractControlDirective, message: string): void { throw new Error(`${message} ${messageEnd}`); } -export function composeValidators(validators: /* Array */ any[]): ValidatorFn { +export function composeValidators(validators: Array): ValidatorFn { return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null; } -export function composeAsyncValidators(validators: /* Array */ any[]): - AsyncValidatorFn { +export function composeAsyncValidators(validators: Array): AsyncValidatorFn { return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) : null; } diff --git a/modules/@angular/forms/src/validators.ts b/modules/@angular/forms/src/validators.ts index c0eea11d5c86c..6bd15db5bbf47 100644 --- a/modules/@angular/forms/src/validators.ts +++ b/modules/@angular/forms/src/validators.ts @@ -6,9 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '@angular/core'; +import {InjectionToken} from '@angular/core'; import {toPromise} from 'rxjs/operator/toPromise'; -import {AsyncValidatorFn, ValidatorFn} from './directives/validators'; + +import {AsyncValidatorFn, Validator, ValidatorFn} from './directives/validators'; import {StringMapWrapper} from './facade/collection'; import {isPresent} from './facade/lang'; import {AbstractControl} from './model'; @@ -29,7 +30,7 @@ function isEmptyInputValue(value: any): boolean { * {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'} * @stable */ -export const NG_VALIDATORS: OpaqueToken = new OpaqueToken('NgValidators'); +export const NG_VALIDATORS = new InjectionToken>('NgValidators'); /** * Providers for asynchronous validators to be used for {@link FormControl}s @@ -41,7 +42,8 @@ export const NG_VALIDATORS: OpaqueToken = new OpaqueToken('NgValidators'); * * @stable */ -export const NG_ASYNC_VALIDATORS: OpaqueToken = new OpaqueToken('NgAsyncValidators'); +export const NG_ASYNC_VALIDATORS = + new InjectionToken>('NgAsyncValidators'); /** * Provides a set of validators used by form controls. diff --git a/modules/@angular/http/test/http_spec.ts b/modules/@angular/http/test/http_spec.ts index 1771b607fb213..bd70b29d94e5a 100644 --- a/modules/@angular/http/test/http_spec.ts +++ b/modules/@angular/http/test/http_spec.ts @@ -42,8 +42,8 @@ export function main() { http = injector.get(Http); jsonp = injector.get(Jsonp); - jsonpBackend = injector.get(JSONPBackend); - xhrBackend = injector.get(XHRBackend); + jsonpBackend = injector.get(JSONPBackend) as MockBackend; + xhrBackend = injector.get(XHRBackend) as any as MockBackend; let xhrCreatedConnections = 0; let jsonpCreatedConnections = 0; diff --git a/modules/@angular/platform-browser/src/dom/dom_tokens.ts b/modules/@angular/platform-browser/src/dom/dom_tokens.ts index 234d877057052..c31db4436f999 100644 --- a/modules/@angular/platform-browser/src/dom/dom_tokens.ts +++ b/modules/@angular/platform-browser/src/dom/dom_tokens.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '@angular/core'; +import {InjectionToken} from '@angular/core'; /** * A DI Token representing the main rendering context. In a browser this is the DOM Document. @@ -16,4 +16,4 @@ import {OpaqueToken} from '@angular/core'; * * @stable */ -export const DOCUMENT: OpaqueToken = new OpaqueToken('DocumentToken'); +export const DOCUMENT = new InjectionToken('DocumentToken'); diff --git a/modules/@angular/platform-browser/src/dom/events/event_manager.ts b/modules/@angular/platform-browser/src/dom/events/event_manager.ts index deb6d12edb556..be89369801795 100644 --- a/modules/@angular/platform-browser/src/dom/events/event_manager.ts +++ b/modules/@angular/platform-browser/src/dom/events/event_manager.ts @@ -6,13 +6,16 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, Injectable, NgZone, OpaqueToken} from '@angular/core'; +import {Inject, Injectable, InjectionToken, NgZone} from '@angular/core'; + import {getDOM} from '../dom_adapter'; + /** * @stable */ -export const EVENT_MANAGER_PLUGINS: OpaqueToken = new OpaqueToken('EventManagerPlugins'); +export const EVENT_MANAGER_PLUGINS = + new InjectionToken('EventManagerPlugins'); /** * @stable diff --git a/modules/@angular/platform-browser/src/dom/events/hammer_gestures.ts b/modules/@angular/platform-browser/src/dom/events/hammer_gestures.ts index 07eba5e9a4867..e3bc720c3d64d 100644 --- a/modules/@angular/platform-browser/src/dom/events/hammer_gestures.ts +++ b/modules/@angular/platform-browser/src/dom/events/hammer_gestures.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, Injectable, OpaqueToken} from '@angular/core'; +import {Inject, Injectable, InjectionToken} from '@angular/core'; import {EventManagerPlugin} from './event_manager'; const EVENT_NAMES = { @@ -53,7 +53,7 @@ const EVENT_NAMES = { * * @experimental */ -export const HAMMER_GESTURE_CONFIG: OpaqueToken = new OpaqueToken('HammerGestureConfig'); +export const HAMMER_GESTURE_CONFIG = new InjectionToken('HammerGestureConfig'); export interface HammerInstance { on(eventName: string, callback: Function): void; diff --git a/modules/@angular/platform-webworker/src/web_workers/shared/api.ts b/modules/@angular/platform-webworker/src/web_workers/shared/api.ts index b8b2d222951be..b030c514c56f5 100644 --- a/modules/@angular/platform-webworker/src/web_workers/shared/api.ts +++ b/modules/@angular/platform-webworker/src/web_workers/shared/api.ts @@ -6,6 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '@angular/core'; +import {InjectionToken} from '@angular/core'; -export const ON_WEB_WORKER = new OpaqueToken('WebWorker.onWebWorker'); +export const ON_WEB_WORKER = new InjectionToken('WebWorker.onWebWorker'); diff --git a/modules/@angular/platform-webworker/src/web_workers/worker/location_providers.ts b/modules/@angular/platform-webworker/src/web_workers/worker/location_providers.ts index 76c8066ffe884..17169053c6c82 100644 --- a/modules/@angular/platform-webworker/src/web_workers/worker/location_providers.ts +++ b/modules/@angular/platform-webworker/src/web_workers/worker/location_providers.ts @@ -7,11 +7,12 @@ */ import {PlatformLocation} from '@angular/common'; -import {APP_INITIALIZER, NgZone} from '@angular/core'; +import {APP_INITIALIZER, InjectionToken, NgZone} from '@angular/core'; import {WebWorkerPlatformLocation} from './platform_location'; + /** * Those providers should be added when the router is used in a worker context in addition to the * {@link ROUTER_PROVIDERS} and after them. diff --git a/modules/@angular/platform-webworker/src/worker_render.ts b/modules/@angular/platform-webworker/src/worker_render.ts index bee7433ca8fd0..3c8d103d70e5e 100644 --- a/modules/@angular/platform-webworker/src/worker_render.ts +++ b/modules/@angular/platform-webworker/src/worker_render.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ErrorHandler, Injectable, Injector, NgZone, OpaqueToken, PLATFORM_INITIALIZER, PlatformRef, Provider, RootRenderer, Testability, createPlatformFactory, isDevMode, platformCore} from '@angular/core'; +import {ErrorHandler, Injectable, InjectionToken, Injector, NgZone, PLATFORM_INITIALIZER, PlatformRef, Provider, RootRenderer, Testability, createPlatformFactory, isDevMode, platformCore} from '@angular/core'; import {AnimationDriver, DOCUMENT, EVENT_MANAGER_PLUGINS, EventManager, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from '@angular/platform-browser'; import {APP_ID_RANDOM_PROVIDER} from './private_import_core'; @@ -21,6 +21,7 @@ import {ServiceMessageBrokerFactory, ServiceMessageBrokerFactory_} from './web_w import {MessageBasedRenderer} from './web_workers/ui/renderer'; + /** * Wrapper class that exposes the Worker * and underlying {@link MessageBus} for lower level message passing. @@ -42,7 +43,7 @@ export class WebWorkerInstance { /** * @experimental WebWorker support is currently experimental. */ -export const WORKER_SCRIPT: OpaqueToken = new OpaqueToken('WebWorkerScript'); +export const WORKER_SCRIPT = new InjectionToken('WebWorkerScript'); /** * A multi-provider used to automatically call the `start()` method after the service is @@ -52,7 +53,7 @@ export const WORKER_SCRIPT: OpaqueToken = new OpaqueToken('WebWorkerScript'); * @experimental WebWorker support is currently experimental. */ export const WORKER_UI_STARTABLE_MESSAGING_SERVICE = - new OpaqueToken('WorkerRenderStartableMsgService'); + new InjectionToken('WorkerRenderStartableMsgService'); export const _WORKER_UI_PLATFORM_PROVIDERS: Provider[] = [ {provide: NgZone, useFactory: createNgZone, deps: []}, diff --git a/modules/@angular/router/src/router_config_loader.ts b/modules/@angular/router/src/router_config_loader.ts index 1643068ab69c8..361e8127001ea 100644 --- a/modules/@angular/router/src/router_config_loader.ts +++ b/modules/@angular/router/src/router_config_loader.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Compiler, ComponentFactoryResolver, Injector, NgModuleFactory, NgModuleFactoryLoader, OpaqueToken} from '@angular/core'; +import {Compiler, ComponentFactoryResolver, InjectionToken, Injector, NgModuleFactory, NgModuleFactoryLoader} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import {fromPromise} from 'rxjs/observable/fromPromise'; import {of } from 'rxjs/observable/of'; @@ -16,10 +16,11 @@ import {mergeMap} from 'rxjs/operator/mergeMap'; import {LoadChildren, Route} from './config'; import {flatten, wrapIntoObservable} from './utils/collection'; + /** * @experimental */ -export const ROUTES = new OpaqueToken('ROUTES'); +export const ROUTES = new InjectionToken('ROUTES'); export class LoadedRouterConfig { constructor( diff --git a/modules/@angular/router/src/router_module.ts b/modules/@angular/router/src/router_module.ts index f4863a3431587..aa5175e3183ab 100644 --- a/modules/@angular/router/src/router_module.ts +++ b/modules/@angular/router/src/router_module.ts @@ -7,7 +7,7 @@ */ import {APP_BASE_HREF, HashLocationStrategy, Location, LocationStrategy, PathLocationStrategy, PlatformLocation} from '@angular/common'; -import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, ApplicationRef, Compiler, ComponentRef, Inject, Injector, ModuleWithProviders, NgModule, NgModuleFactoryLoader, NgProbeToken, OpaqueToken, Optional, Provider, SkipSelf, SystemJsNgModuleLoader} from '@angular/core'; +import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, ApplicationRef, Compiler, ComponentRef, Inject, InjectionToken, Injector, ModuleWithProviders, NgModule, NgModuleFactoryLoader, NgProbeToken, Optional, Provider, SkipSelf, SystemJsNgModuleLoader} from '@angular/core'; import {Route, Routes} from './config'; import {RouterLink, RouterLinkWithHref} from './directives/router_link'; @@ -36,12 +36,12 @@ const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterL * @whatItDoes Is used in DI to configure the router. * @stable */ -export const ROUTER_CONFIGURATION = new OpaqueToken('ROUTER_CONFIGURATION'); +export const ROUTER_CONFIGURATION = new InjectionToken('ROUTER_CONFIGURATION'); /** * @docsNotRequired */ -export const ROUTER_FORROOT_GUARD = new OpaqueToken('ROUTER_FORROOT_GUARD'); +export const ROUTER_FORROOT_GUARD = new InjectionToken('ROUTER_FORROOT_GUARD'); export const ROUTER_PROVIDERS: Provider[] = [ Location, @@ -301,7 +301,8 @@ export function initialRouterNavigation( * * @experimental */ -export const ROUTER_INITIALIZER = new OpaqueToken('Router Initializer'); +export const ROUTER_INITIALIZER = + new InjectionToken<(compRef: ComponentRef) => void>('Router Initializer'); export function provideRouterInitializer() { return [ diff --git a/modules/@angular/router/upgrade.ts b/modules/@angular/router/upgrade.ts index c4ab90fe1cdd9..a51d61fb754bc 100644 --- a/modules/@angular/router/upgrade.ts +++ b/modules/@angular/router/upgrade.ts @@ -6,11 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import {APP_BOOTSTRAP_LISTENER, ApplicationRef, OpaqueToken} from '@angular/core'; +import {APP_BOOTSTRAP_LISTENER, ApplicationRef, ComponentRef, InjectionToken} from '@angular/core'; import {ExtraOptions, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, Router, RouterPreloader} from '@angular/router'; import {UpgradeModule} from '@angular/upgrade/static'; + /** * @whatItDoes Creates an initializer that in addition to setting up the Angular 2 * router sets up the ngRoute integration. @@ -57,7 +58,7 @@ export function initialRouterNavigation( const router = ngUpgrade.injector.get(Router); const ref = ngUpgrade.injector.get(ApplicationRef); - router.resetRootComponentType(ref.componentTypes[0]); + (router as any).resetRootComponentType(ref.componentTypes[0]); preloader.setUpPreloading(); if (opts.initialNavigation === false) { router.setUpLocationChangeListener(); @@ -86,4 +87,4 @@ export function setUpLocationSync(ngUpgrade: UpgradeModule): void { url.href = next; router.navigateByUrl(url.pathname); }); -} \ No newline at end of file +} diff --git a/modules/@angular/upgrade/test/aot/integration/injection_spec.ts b/modules/@angular/upgrade/test/aot/integration/injection_spec.ts index 025f4a8a0bd91..26f07429be694 100644 --- a/modules/@angular/upgrade/test/aot/integration/injection_spec.ts +++ b/modules/@angular/upgrade/test/aot/integration/injection_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {NgModule, OpaqueToken, destroyPlatform} from '@angular/core'; +import {InjectionToken, NgModule, destroyPlatform} from '@angular/core'; import {async} from '@angular/core/testing'; import {BrowserModule} from '@angular/platform-browser'; import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; @@ -23,7 +23,7 @@ export function main() { it('should downgrade ng2 service to ng1', async(() => { // Tokens used in ng2 to identify services - const Ng2Service = new OpaqueToken('ng2-service'); + const Ng2Service = new InjectionToken('ng2-service'); // Sample ng1 NgModule for tests @NgModule({ @@ -49,7 +49,7 @@ export function main() { it('should upgrade ng1 service to ng2', async(() => { // Tokens used in ng2 to identify services - const Ng1Service = new OpaqueToken('ng1-service'); + const Ng1Service = new InjectionToken('ng1-service'); // Sample ng1 NgModule for tests @NgModule({ diff --git a/modules/angular1_router/src/module_template.js b/modules/angular1_router/src/module_template.js index d40a68ded780c..7f8eb3c90488c 100644 --- a/modules/angular1_router/src/module_template.js +++ b/modules/angular1_router/src/module_template.js @@ -45,7 +45,7 @@ function routerFactory($q, $location, $browser, $rootScope, $injector, $routerRo var exports = { Injectable: function () {}, - OpaqueToken: function () {}, + InjectionToken: function () {}, Inject: function () {} }; var routerRequire = function () {return exports;}; diff --git a/tools/public_api_guard/common/index.d.ts b/tools/public_api_guard/common/index.d.ts index eb2bff554f832..6384324f1fd6a 100644 --- a/tools/public_api_guard/common/index.d.ts +++ b/tools/public_api_guard/common/index.d.ts @@ -1,5 +1,5 @@ /** @stable */ -export declare const APP_BASE_HREF: OpaqueToken; +export declare const APP_BASE_HREF: InjectionToken; /** @stable */ export declare class AsyncPipe implements OnDestroy { diff --git a/tools/public_api_guard/core/index.d.ts b/tools/public_api_guard/core/index.d.ts index eea35cc56904f..b59124e704069 100644 --- a/tools/public_api_guard/core/index.d.ts +++ b/tools/public_api_guard/core/index.d.ts @@ -19,7 +19,7 @@ export declare abstract class AfterViewInit { } /** @experimental */ -export declare const ANALYZE_FOR_ENTRY_COMPONENTS: OpaqueToken; +export declare const ANALYZE_FOR_ENTRY_COMPONENTS: InjectionToken; /** @experimental */ export declare function animate(timing: string | number, styles?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata): AnimationAnimateMetadata; @@ -131,13 +131,13 @@ export declare abstract class AnimationWithStepsMetadata extends AnimationMetada } /** @experimental */ -export declare const APP_BOOTSTRAP_LISTENER: OpaqueToken; +export declare const APP_BOOTSTRAP_LISTENER: InjectionToken<((compRef: ComponentRef) => void)[]>; /** @experimental */ -export declare const APP_ID: any; +export declare const APP_ID: InjectionToken; /** @experimental */ -export declare const APP_INITIALIZER: any; +export declare const APP_INITIALIZER: InjectionToken<(() => void)[]>; /** @experimental */ export declare class ApplicationInitStatus { @@ -221,7 +221,12 @@ export declare class Compiler { } /** @experimental */ -export declare const COMPILER_OPTIONS: OpaqueToken; +export declare const COMPILER_OPTIONS: InjectionToken<{ + useDebug?: boolean; + useJit?: boolean; + defaultEncapsulation?: ViewEncapsulation; + providers?: any[]; +}[]>; /** @experimental */ export declare abstract class CompilerFactory { @@ -491,9 +496,16 @@ export interface InjectDecorator { new (token: any): Inject; } +/** @stable */ +export declare class InjectionToken extends OpaqueToken { + constructor(desc: string); + toString(): string; +} + /** @stable */ export declare abstract class Injector { - get(token: any, notFoundValue?: any): any; + get(token: Type | InjectionToken, notFoundValue?: T): T; + /** @deprecated */ get(token: any, notFoundValue?: any): any; static NULL: Injector; static THROW_IF_NOT_FOUND: Object; } @@ -586,7 +598,7 @@ export declare class KeyValueDiffers { } /** @experimental */ -export declare const LOCALE_ID: OpaqueToken; +export declare const LOCALE_ID: InjectionToken; /** @experimental */ export declare class ModuleWithComponentFactories { @@ -672,8 +684,9 @@ export declare abstract class OnInit { abstract ngOnInit(): void; } -/** @stable */ +/** @deprecated */ export declare class OpaqueToken { + protected _desc: string; constructor(_desc: string); toString(): string; } @@ -691,7 +704,7 @@ export interface OptionalDecorator { export declare const Output: OutputDecorator; /** @experimental */ -export declare const PACKAGE_ROOT_URL: any; +export declare const PACKAGE_ROOT_URL: InjectionToken; /** @stable */ export declare const Pipe: PipeDecorator; @@ -702,7 +715,7 @@ export interface PipeTransform { } /** @experimental */ -export declare const PLATFORM_INITIALIZER: any; +export declare const PLATFORM_INITIALIZER: InjectionToken<(() => void)[]>; /** @experimental */ export declare const platformCore: (extraProviders?: Provider[]) => PlatformRef; @@ -946,10 +959,10 @@ export interface TrackByFn { export declare function transition(stateChangeExpr: string | ((fromState: string, toState: string) => boolean), steps: AnimationMetadata | AnimationMetadata[]): AnimationStateTransitionMetadata; /** @experimental */ -export declare const TRANSLATIONS: OpaqueToken; +export declare const TRANSLATIONS: InjectionToken; /** @experimental */ -export declare const TRANSLATIONS_FORMAT: OpaqueToken; +export declare const TRANSLATIONS_FORMAT: InjectionToken; /** @experimental */ export declare function trigger(name: string, animation: AnimationMetadata[]): AnimationEntryMetadata; diff --git a/tools/public_api_guard/core/testing/index.d.ts b/tools/public_api_guard/core/testing/index.d.ts index e29bd7c1b1699..1bcc8a6ce968c 100644 --- a/tools/public_api_guard/core/testing/index.d.ts +++ b/tools/public_api_guard/core/testing/index.d.ts @@ -20,10 +20,10 @@ export declare class ComponentFixture { } /** @experimental */ -export declare const ComponentFixtureAutoDetect: OpaqueToken; +export declare const ComponentFixtureAutoDetect: InjectionToken; /** @experimental */ -export declare const ComponentFixtureNoNgZone: OpaqueToken; +export declare const ComponentFixtureNoNgZone: InjectionToken; /** @experimental */ export declare function discardPeriodicTasks(): void; diff --git a/tools/public_api_guard/forms/index.d.ts b/tools/public_api_guard/forms/index.d.ts index a257a499d5467..9ce723aaef515 100644 --- a/tools/public_api_guard/forms/index.d.ts +++ b/tools/public_api_guard/forms/index.d.ts @@ -355,13 +355,13 @@ export declare class MinLengthValidator implements Validator, OnChanges { } /** @stable */ -export declare const NG_ASYNC_VALIDATORS: OpaqueToken; +export declare const NG_ASYNC_VALIDATORS: InjectionToken<(Function | Validator)[]>; /** @stable */ -export declare const NG_VALIDATORS: OpaqueToken; +export declare const NG_VALIDATORS: InjectionToken<(Function | Validator)[]>; /** @stable */ -export declare const NG_VALUE_ACCESSOR: OpaqueToken; +export declare const NG_VALUE_ACCESSOR: InjectionToken; /** @stable */ export declare abstract class NgControl extends AbstractControlDirective { diff --git a/tools/public_api_guard/platform-browser/index.d.ts b/tools/public_api_guard/platform-browser/index.d.ts index e66bd0cb56190..4e3b75ef6af1d 100644 --- a/tools/public_api_guard/platform-browser/index.d.ts +++ b/tools/public_api_guard/platform-browser/index.d.ts @@ -20,7 +20,7 @@ export declare class By { export declare function disableDebugTools(): void; /** @stable */ -export declare const DOCUMENT: OpaqueToken; +export declare const DOCUMENT: InjectionToken; /** @stable */ export declare abstract class DomSanitizer implements Sanitizer { @@ -36,7 +36,7 @@ export declare abstract class DomSanitizer implements Sanitizer { export declare function enableDebugTools(ref: ComponentRef): ComponentRef; /** @stable */ -export declare const EVENT_MANAGER_PLUGINS: OpaqueToken; +export declare const EVENT_MANAGER_PLUGINS: InjectionToken; /** @stable */ export declare class EventManager { @@ -47,7 +47,7 @@ export declare class EventManager { } /** @experimental */ -export declare const HAMMER_GESTURE_CONFIG: OpaqueToken; +export declare const HAMMER_GESTURE_CONFIG: InjectionToken; /** @experimental */ export declare class HammerGestureConfig { diff --git a/tools/public_api_guard/platform-webworker/index.d.ts b/tools/public_api_guard/platform-webworker/index.d.ts index a9e14b64ccdf9..0eb94f897a8bc 100644 --- a/tools/public_api_guard/platform-webworker/index.d.ts +++ b/tools/public_api_guard/platform-webworker/index.d.ts @@ -85,7 +85,7 @@ export declare const WORKER_APP_LOCATION_PROVIDERS: ({ provide: typeof PlatformLocation; useClass: typeof WebWorkerPlatformLocation; } | { - provide: any; + provide: InjectionToken<(() => void)[]>; useFactory: (platformLocation: WebWorkerPlatformLocation, zone: NgZone) => () => Promise; multi: boolean; deps: (typeof NgZone | typeof PlatformLocation)[]; diff --git a/tools/public_api_guard/router/index.d.ts b/tools/public_api_guard/router/index.d.ts index 075743c3ecc1f..641beddecc4db 100644 --- a/tools/public_api_guard/router/index.d.ts +++ b/tools/public_api_guard/router/index.d.ts @@ -223,10 +223,10 @@ export declare class Router { } /** @stable */ -export declare const ROUTER_CONFIGURATION: OpaqueToken; +export declare const ROUTER_CONFIGURATION: InjectionToken; /** @experimental */ -export declare const ROUTER_INITIALIZER: OpaqueToken; +export declare const ROUTER_INITIALIZER: InjectionToken<(compRef: ComponentRef) => void>; /** @experimental */ export declare abstract class RouteReuseStrategy {