feat(core): Add type information to injector.get() (#13785)

- Introduce `InjectionToken<T>` which is a parameterized and type-safe
  version of `OpaqueToken`.

DEPRECATION:
- `OpaqueToken` is now deprecated, use `InjectionToken<T>` instead.
- `Injector.get(token: any, notFoundValue?: any): any` is now deprecated
  use the same method which is now overloaded as
  `Injector.get<T>(token: Type<T>|InjectionToken<T>, 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
This commit is contained in:
Miško Hevery 2017-01-03 16:54:46 -08:00 committed by Miško Hevery
parent 6d1f1a43bb
commit d169c2434e
59 changed files with 255 additions and 175 deletions

View File

@ -9,7 +9,7 @@
// Must be imported first, because angular2 decorators throws on load. // Must be imported first, because angular2 decorators throws on load.
import 'reflect-metadata'; 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 {Options} from './src/common_options';
export {MeasureValues} from './src/measure_values'; export {MeasureValues} from './src/measure_values';
export {Metric} from './src/metric'; export {Metric} from './src/metric';

View File

@ -6,26 +6,26 @@
* found in the LICENSE file at https://angular.io/license * 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'; import * as fs from 'fs';
export class Options { export class Options {
static SAMPLE_ID = new OpaqueToken('Options.sampleId'); static SAMPLE_ID = new InjectionToken('Options.sampleId');
static DEFAULT_DESCRIPTION = new OpaqueToken('Options.defaultDescription'); static DEFAULT_DESCRIPTION = new InjectionToken('Options.defaultDescription');
static SAMPLE_DESCRIPTION = new OpaqueToken('Options.sampleDescription'); static SAMPLE_DESCRIPTION = new InjectionToken('Options.sampleDescription');
static FORCE_GC = new OpaqueToken('Options.forceGc'); static FORCE_GC = new InjectionToken('Options.forceGc');
static NO_PREPARE = () => true; static NO_PREPARE = () => true;
static PREPARE = new OpaqueToken('Options.prepare'); static PREPARE = new InjectionToken('Options.prepare');
static EXECUTE = new OpaqueToken('Options.execute'); static EXECUTE = new InjectionToken('Options.execute');
static CAPABILITIES = new OpaqueToken('Options.capabilities'); static CAPABILITIES = new InjectionToken('Options.capabilities');
static USER_AGENT = new OpaqueToken('Options.userAgent'); static USER_AGENT = new InjectionToken('Options.userAgent');
static MICRO_METRICS = new OpaqueToken('Options.microMetrics'); static MICRO_METRICS = new InjectionToken('Options.microMetrics');
static USER_METRICS = new OpaqueToken('Options.userMetrics'); static USER_METRICS = new InjectionToken('Options.userMetrics');
static NOW = new OpaqueToken('Options.now'); static NOW = new InjectionToken('Options.now');
static WRITE_FILE = new OpaqueToken('Options.writeFile'); static WRITE_FILE = new InjectionToken('Options.writeFile');
static RECEIVED_DATA = new OpaqueToken('Options.receivedData'); static RECEIVED_DATA = new InjectionToken('Options.receivedData');
static REQUEST_COUNT = new OpaqueToken('Options.requestCount'); static REQUEST_COUNT = new InjectionToken('Options.requestCount');
static CAPTURE_FRAMES = new OpaqueToken('Options.frameCapture'); static CAPTURE_FRAMES = new InjectionToken('Options.frameCapture');
static DEFAULT_PROVIDERS = [ static DEFAULT_PROVIDERS = [
{provide: Options.DEFAULT_DESCRIPTION, useValue: {}}, {provide: Options.DEFAULT_DESCRIPTION, useValue: {}},
{provide: Options.SAMPLE_DESCRIPTION, useValue: {}}, {provide: Options.SAMPLE_DESCRIPTION, useValue: {}},

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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'; import {Metric} from '../metric';
@ -60,4 +60,4 @@ function mergeStringMaps(maps: {[key: string]: string}[]): {[key: string]: strin
return result; return result;
} }
const _CHILDREN = new OpaqueToken('MultiMetric.children'); const _CHILDREN = new InjectionToken('MultiMetric.children');

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {Options} from '../common_options';
import {Metric} from '../metric'; import {Metric} from '../metric';
@ -18,7 +18,7 @@ import {PerfLogEvent, PerfLogFeatures, WebDriverExtension} from '../web_driver_e
*/ */
@Injectable() @Injectable()
export class PerflogMetric extends Metric { export class PerflogMetric extends Metric {
static SET_TIMEOUT = new OpaqueToken('PerflogMetric.setTimeout'); static SET_TIMEOUT = new InjectionToken('PerflogMetric.setTimeout');
static PROVIDERS = [ static PROVIDERS = [
PerflogMetric, { PerflogMetric, {
provide: PerflogMetric.SET_TIMEOUT, provide: PerflogMetric.SET_TIMEOUT,

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {print} from '../facade/lang';
import {MeasureValues} from '../measure_values'; import {MeasureValues} from '../measure_values';
import {Reporter} from '../reporter'; import {Reporter} from '../reporter';
@ -20,8 +20,8 @@ import {formatNum, formatStats, sortedProps} from './util';
*/ */
@Injectable() @Injectable()
export class ConsoleReporter extends Reporter { export class ConsoleReporter extends Reporter {
static PRINT = new OpaqueToken('ConsoleReporter.print'); static PRINT = new InjectionToken('ConsoleReporter.print');
static COLUMN_WIDTH = new OpaqueToken('ConsoleReporter.columnWidth'); static COLUMN_WIDTH = new InjectionToken('ConsoleReporter.columnWidth');
static PROVIDERS = [ static PROVIDERS = [
ConsoleReporter, {provide: ConsoleReporter.COLUMN_WIDTH, useValue: 18}, ConsoleReporter, {provide: ConsoleReporter.COLUMN_WIDTH, useValue: 18},
{provide: ConsoleReporter.PRINT, useValue: print} {provide: ConsoleReporter.PRINT, useValue: print}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {Options} from '../common_options';
import {MeasureValues} from '../measure_values'; import {MeasureValues} from '../measure_values';
@ -21,7 +21,7 @@ import {formatStats, sortedProps} from './util';
*/ */
@Injectable() @Injectable()
export class JsonFileReporter extends Reporter { export class JsonFileReporter extends Reporter {
static PATH = new OpaqueToken('JsonFileReporter.path'); static PATH = new InjectionToken('JsonFileReporter.path');
static PROVIDERS = [JsonFileReporter, {provide: JsonFileReporter.PATH, useValue: '.'}]; static PROVIDERS = [JsonFileReporter, {provide: JsonFileReporter.PATH, useValue: '.'}];
constructor( constructor(

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {MeasureValues} from '../measure_values';
import {Reporter} from '../reporter'; 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');

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {Options} from './common_options';
import {Metric} from './metric'; import {Metric} from './metric';

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {MeasureValues} from '../measure_values';
import {Statistic} from '../statistic'; import {Statistic} from '../statistic';
@ -18,8 +18,8 @@ import {Validator} from '../validator';
*/ */
@Injectable() @Injectable()
export class RegressionSlopeValidator extends Validator { export class RegressionSlopeValidator extends Validator {
static SAMPLE_SIZE = new OpaqueToken('RegressionSlopeValidator.sampleSize'); static SAMPLE_SIZE = new InjectionToken('RegressionSlopeValidator.sampleSize');
static METRIC = new OpaqueToken('RegressionSlopeValidator.metric'); static METRIC = new InjectionToken('RegressionSlopeValidator.metric');
static PROVIDERS = [ static PROVIDERS = [
RegressionSlopeValidator, {provide: RegressionSlopeValidator.SAMPLE_SIZE, useValue: 10}, RegressionSlopeValidator, {provide: RegressionSlopeValidator.SAMPLE_SIZE, useValue: 10},
{provide: RegressionSlopeValidator.METRIC, useValue: 'scriptTime'} {provide: RegressionSlopeValidator.METRIC, useValue: 'scriptTime'}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {MeasureValues} from '../measure_values';
import {Validator} from '../validator'; import {Validator} from '../validator';
@ -16,7 +16,7 @@ import {Validator} from '../validator';
*/ */
@Injectable() @Injectable()
export class SizeValidator extends Validator { 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}]; static PROVIDERS = [SizeValidator, {provide: SizeValidator.SAMPLE_SIZE, useValue: 10}];
constructor(@Inject(SizeValidator.SAMPLE_SIZE) private _sampleSize: number) { super(); } constructor(@Inject(SizeValidator.SAMPLE_SIZE) private _sampleSize: number) { super(); }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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'; import {Options} from './common_options';
@ -101,4 +101,4 @@ export class PerfLogFeatures {
} }
} }
const _CHILDREN = new OpaqueToken('WebDriverExtension.children'); const _CHILDREN = new InjectionToken('WebDriverExtension.children');

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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'; import {LocationChangeListener} from './platform_location';
/** /**
@ -61,4 +61,4 @@ export abstract class LocationStrategy {
* *
* @stable * @stable
*/ */
export const APP_BASE_HREF: OpaqueToken = new OpaqueToken('appBaseHref'); export const APP_BASE_HREF = new InjectionToken<string>('appBaseHref');

View File

@ -8,7 +8,7 @@
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {NgComponentOutlet} from '@angular/common/src/directives/ng_component_outlet'; 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 {TestBed, async} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers'; 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'}) @Component({selector: 'injected-component', template: 'foo'})
class InjectedComponent { class InjectedComponent {
constructor(@Optional() @Inject(TEST_TOKEN) public testToken: any) {} constructor(@Optional() @Inject(TEST_TOKEN) public testToken: any) {}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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'; import {BasicComp} from './basic';
@ -15,7 +15,7 @@ export class CompWithEntryComponents {
constructor(public cfr: ComponentFactoryResolver) {} constructor(public cfr: ComponentFactoryResolver) {}
} }
export const SOME_TOKEN = new OpaqueToken('someToken'); export const SOME_TOKEN = new InjectionToken('someToken');
export function provideValueWithEntryComponents(value: any) { export function provideValueWithEntryComponents(value: any) {
return [ return [

View File

@ -7,21 +7,21 @@
*/ */
import * as common from '@angular/common'; 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 {Observable} from 'rxjs/Observable';
import {wrapInArray} from './funcs'; import {wrapInArray} from './funcs';
export const SOME_OPAQUE_TOKEN = new OpaqueToken('opaqueToken'); export const SOME_INJECTON_TOKEN = new InjectionToken('injectionToken');
@Component({ @Component({
selector: 'comp-providers', selector: 'comp-providers',
template: '', template: '',
providers: [ providers: [
{provide: 'strToken', useValue: 'strValue'}, {provide: 'strToken', useValue: 'strValue'},
{provide: SOME_OPAQUE_TOKEN, useValue: 10}, {provide: SOME_INJECTON_TOKEN, useValue: 10},
{provide: 'reference', useValue: common.NgIf}, {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 { export class CompWithProviders {

View File

@ -7,7 +7,7 @@
*/ */
import {LowerCasePipe, NgIf} from '@angular/common'; 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() @Injectable()
export class SomeService { export class SomeService {
@ -48,7 +48,7 @@ export class CompUsingRootModuleDirectiveAndPipe {
export class CompUsingLibModuleDirectiveAndPipe { export class CompUsingLibModuleDirectiveAndPipe {
} }
export const SOME_TOKEN = new OpaqueToken('someToken'); export const SOME_TOKEN = new InjectionToken('someToken');
export function provideValueWithEntryComponents(value: any) { export function provideValueWithEntryComponents(value: any) {
return [ return [

View File

@ -17,7 +17,8 @@ const ANGULAR_IMPORT_LOCATIONS = {
coreDecorators: '@angular/core/src/metadata', coreDecorators: '@angular/core/src/metadata',
diDecorators: '@angular/core/src/di/metadata', diDecorators: '@angular/core/src/di/metadata',
diMetadata: '@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', animationMetadata: '@angular/core/src/animation/metadata',
provider: '@angular/core/src/di/provider' provider: '@angular/core/src/di/provider'
}; };
@ -34,6 +35,7 @@ export class StaticReflector implements ReflectorReader {
private parameterCache = new Map<StaticSymbol, any[]>(); private parameterCache = new Map<StaticSymbol, any[]>();
private methodCache = new Map<StaticSymbol, {[key: string]: boolean}>(); private methodCache = new Map<StaticSymbol, {[key: string]: boolean}>();
private conversionMap = new Map<StaticSymbol, (context: StaticSymbol, args: any[]) => any>(); private conversionMap = new Map<StaticSymbol, (context: StaticSymbol, args: any[]) => any>();
private injectionToken: StaticSymbol;
private opaqueToken: StaticSymbol; private opaqueToken: StaticSymbol;
constructor( constructor(
@ -229,9 +231,10 @@ export class StaticReflector implements ReflectorReader {
} }
private initializeConversionMap(): void { private initializeConversionMap(): void {
const {coreDecorators, diDecorators, diMetadata, diOpaqueToken, animationMetadata, provider} = const {coreDecorators, diDecorators, diMetadata, diInjectionToken,
ANGULAR_IMPORT_LOCATIONS; diOpaqueToken, animationMetadata, provider} = ANGULAR_IMPORT_LOCATIONS;
this.opaqueToken = this.findDeclaration(diOpaqueToken, 'OpaqueToken'); this.injectionToken = this.findDeclaration(diInjectionToken, 'InjectionToken');
this.opaqueToken = this.findDeclaration(diInjectionToken, 'OpaqueToken');
this._registerDecoratorOrConstructor(this.findDeclaration(diDecorators, 'Host'), Host); this._registerDecoratorOrConstructor(this.findDeclaration(diDecorators, 'Host'), Host);
this._registerDecoratorOrConstructor( this._registerDecoratorOrConstructor(
@ -382,7 +385,8 @@ export class StaticReflector implements ReflectorReader {
} }
if (expression instanceof StaticSymbol) { if (expression instanceof StaticSymbol) {
// Stop simplification at builtin symbols // 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; return expression;
} else { } else {
const staticSymbol = expression; const staticSymbol = expression;
@ -506,9 +510,9 @@ export class StaticReflector implements ReflectorReader {
// Determine if the function is a built-in conversion // Determine if the function is a built-in conversion
staticSymbol = simplifyInContext(context, expression['expression'], depth + 1); staticSymbol = simplifyInContext(context, expression['expression'], depth + 1);
if (staticSymbol instanceof StaticSymbol) { if (staticSymbol instanceof StaticSymbol) {
if (staticSymbol === self.opaqueToken) { if (staticSymbol === self.injectionToken || staticSymbol === self.opaqueToken) {
// if somebody calls new OpaqueToken, don't create an OpaqueToken, // if somebody calls new InjectionToken, don't create an InjectionToken,
// but rather return the symbol to which the OpaqueToken is assigned to. // but rather return the symbol to which the InjectionToken is assigned to.
return context; return context;
} }
const argExpressions: any[] = expression['arguments'] || []; 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).line = line;
(result as any).column = column; (result as any).column = column;
return result; return result;
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {AnimationParser} from '../animation/animation_parser';
import {CompilerConfig} from '../config'; 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}"`);} `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 * A set of providers that provide `JitCompiler` and its dependencies to use for

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {StaticSymbol, StaticSymbolCache} from './aot/static_symbol';
import {ngfactoryFilePath} from './aot/util'; import {ngfactoryFilePath} from './aot/util';
@ -27,7 +27,7 @@ import {getUrlScheme} from './url_resolver';
import {MODULE_SUFFIX, SyntaxError, ValueTransformer, visitValue} from './util'; import {MODULE_SUFFIX, SyntaxError, ValueTransformer, visitValue} from './util';
export type ErrorCollector = (error: any, type?: any) => void; 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: // Design notes:
// - don't lazily create metadata: // - don't lazily create metadata:

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeSummary, CompileTemplateSummary, CompileTokenMetadata, CompileTypeMetadata, identifierName} from '../compile_metadata';
import {Parser} from '../expression_parser/parser'; import {Parser} from '../expression_parser/parser';
import {isPresent} from '../facade/lang'; 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. * 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 { export class TemplateParseError extends ParseError {
constructor(message: string, span: ParseSourceSpan, level: ParseErrorLevel) { constructor(message: string, span: ParseSourceSpan, level: ParseErrorLevel) {

View File

@ -6,12 +6,13 @@
* found in the LICENSE file at https://angular.io/license * 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 {isBlank, isPresent} from './facade/lang';
import {CompilerInjectable} from './injectable'; import {CompilerInjectable} from './injectable';
/** /**
* Create a {@link UrlResolver} with no package prefix. * Create a {@link UrlResolver} with no package prefix.
*/ */

View File

@ -8,14 +8,14 @@
import {isPromise} from '../src/util/lang'; 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. * A function that will be executed when an application is initialized.
* @experimental * @experimental
*/ */
export const APP_INITIALIZER: any = new OpaqueToken('Application Initializer'); export const APP_INITIALIZER = new InjectionToken<Array<() => void>>('Application Initializer');
/** /**
* A class that reflects the state of running {@link APP_INITIALIZER}s. * A class that reflects the state of running {@link APP_INITIALIZER}s.

View File

@ -16,7 +16,7 @@ import {ApplicationInitStatus} from './application_init';
import {APP_BOOTSTRAP_LISTENER, PLATFORM_INITIALIZER} from './application_tokens'; import {APP_BOOTSTRAP_LISTENER, PLATFORM_INITIALIZER} from './application_tokens';
import {ChangeDetectorRef} from './change_detection/change_detector_ref'; import {ChangeDetectorRef} from './change_detection/change_detector_ref';
import {Console} from './console'; 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 {CompilerFactory, CompilerOptions} from './linker/compiler';
import {ComponentFactory, ComponentRef} from './linker/component_factory'; import {ComponentFactory, ComponentRef} from './linker/component_factory';
import {ComponentFactoryResolver} from './linker/component_factory_resolver'; 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.'); 'There can be only one platform. Destroy the previous one to create a new one.');
} }
_platform = injector.get(PlatformRef); _platform = injector.get(PlatformRef);
const inits: Function[] = <Function[]>injector.get(PLATFORM_INITIALIZER, null); const inits = injector.get(PLATFORM_INITIALIZER, null);
if (inits) inits.forEach(init => init()); if (inits) inits.forEach(init => init());
return _platform; return _platform;
} }
@ -96,7 +96,7 @@ export function createPlatform(injector: Injector): PlatformRef {
export function createPlatformFactory( export function createPlatformFactory(
parentPlatformFactory: (extraProviders?: Provider[]) => PlatformRef, name: string, parentPlatformFactory: (extraProviders?: Provider[]) => PlatformRef, name: string,
providers: Provider[] = []): (extraProviders?: Provider[]) => PlatformRef { providers: Provider[] = []): (extraProviders?: Provider[]) => PlatformRef {
const marker = new OpaqueToken(`Platform: ${name}`); const marker = new InjectionToken(`Platform: ${name}`);
return (extraProviders: Provider[] = []) => { return (extraProviders: Provider[] = []) => {
if (!getPlatform()) { if (!getPlatform()) {
if (parentPlatformFactory) { if (parentPlatformFactory) {
@ -413,7 +413,7 @@ export class ApplicationRef_ extends ApplicationRef {
/** @internal */ /** @internal */
static _tickScope: WtfScopeFn = wtfCreateScope('ApplicationRef#tick()'); static _tickScope: WtfScopeFn = wtfCreateScope('ApplicationRef#tick()');
private _bootstrapListeners: Function[] = []; private _bootstrapListeners: ((compRef: ComponentRef<any>) => void)[] = [];
private _rootComponents: ComponentRef<any>[] = []; private _rootComponents: ComponentRef<any>[] = [];
private _rootComponentTypes: Type<any>[] = []; private _rootComponentTypes: Type<any>[] = [];
private _views: AppView<any>[] = []; private _views: AppView<any>[] = [];
@ -480,8 +480,7 @@ export class ApplicationRef_ extends ApplicationRef {
this._rootComponents.push(componentRef); this._rootComponents.push(componentRef);
// Get the listeners lazily to prevent DI cycles. // Get the listeners lazily to prevent DI cycles.
const listeners = const listeners =
<((compRef: ComponentRef<any>) => void)[]>this._injector.get(APP_BOOTSTRAP_LISTENER, []) this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners);
.concat(this._bootstrapListeners);
listeners.forEach((listener) => listener(componentRef)); listeners.forEach((listener) => listener(componentRef));
} }

View File

@ -6,7 +6,8 @@
* found in the LICENSE file at https://angular.io/license * 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. * using this token.
* @experimental * @experimental
*/ */
export const APP_ID: any = new OpaqueToken('AppId'); export const APP_ID = new InjectionToken<string>('AppId');
export function _appIdRandomProviderFactory() { export function _appIdRandomProviderFactory() {
return `${_randomChar()}${_randomChar()}${_randomChar()}`; return `${_randomChar()}${_randomChar()}${_randomChar()}`;
@ -43,7 +44,7 @@ function _randomChar(): string {
* A function that will be executed when a platform is initialized. * A function that will be executed when a platform is initialized.
* @experimental * @experimental
*/ */
export const PLATFORM_INITIALIZER: any = new OpaqueToken('Platform Initializer'); export const PLATFORM_INITIALIZER = new InjectionToken<Array<() => void>>('Platform Initializer');
/** /**
* All callbacks provided via this token will be called for every component that is bootstrapped. * 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 * @experimental
*/ */
export const APP_BOOTSTRAP_LISTENER = new OpaqueToken('appBootstrapListener'); export const APP_BOOTSTRAP_LISTENER =
new InjectionToken<Array<(compRef: ComponentRef<any>) => void>>('appBootstrapListener');
/** /**
* A token which indicates the root directory of the application * A token which indicates the root directory of the application
* @experimental * @experimental
*/ */
export const PACKAGE_ROOT_URL: any = new OpaqueToken('Application Packages Root URL'); export const PACKAGE_ROOT_URL = new InjectionToken<string>('Application Packages Root URL');

View File

@ -21,4 +21,4 @@ export {ReflectiveInjector} from './di/reflective_injector';
export {Provider, TypeProvider, ValueProvider, ClassProvider, ExistingProvider, FactoryProvider} from './di/provider'; export {Provider, TypeProvider, ValueProvider, ClassProvider, ExistingProvider, FactoryProvider} from './di/provider';
export {ResolvedReflectiveFactory, ResolvedReflectiveProvider} from './di/reflective_provider'; export {ResolvedReflectiveFactory, ResolvedReflectiveProvider} from './di/reflective_provider';
export {ReflectiveKey} from './di/reflective_key'; export {ReflectiveKey} from './di/reflective_key';
export {OpaqueToken} from './di/opaque_token'; export {InjectionToken, OpaqueToken} from './di/injection_token';

View File

@ -26,10 +26,42 @@
* *
* Using an `OpaqueToken` is preferable to using an `Object` as tokens because it provides better * Using an `OpaqueToken` is preferable to using an `Object` as tokens because it provides better
* error messages. * error messages.
* @stable * @deprecated since v4.0.0 because it does not support type information, use `InjectionToken<?>`
* instead.
*/ */
export class OpaqueToken { export class OpaqueToken {
constructor(private _desc: string) {} constructor(protected _desc: string) {}
toString(): string { return `Token ${this._desc}`; } 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<MyInterface>('SomeToken'));
* // myInterface is inferred to be MyInterface.
* ```
*
* ### Example
*
* {@example core/di/ts/injector_spec.ts region='Injector'}
*
* @stable
*/
export class InjectionToken<T> 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}`; }
}

View File

@ -8,6 +8,9 @@
import {unimplemented} from '../facade/errors'; import {unimplemented} from '../facade/errors';
import {stringify} from '../facade/lang'; import {stringify} from '../facade/lang';
import {Type} from '../type';
import {InjectionToken} from './injection_token';
const _THROW_IF_NOT_FOUND = new Object(); const _THROW_IF_NOT_FOUND = new Object();
export const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND; 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 * Injector.THROW_IF_NOT_FOUND is given
* - Returns the `notFoundValue` otherwise * - Returns the `notFoundValue` otherwise
*/ */
get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T): T;
/**
* @deprecated from v4.0.0 use Type<T> or InjectToken<T>
*/
get(token: any, notFoundValue?: any): any;
get(token: any, notFoundValue?: any): any { return unimplemented(); } get(token: any, notFoundValue?: any): any { return unimplemented(); }
} }

View File

@ -52,7 +52,7 @@ export interface TypeProvider extends Type<any> {}
*/ */
export interface ValueProvider { 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; provide: any;
@ -96,7 +96,7 @@ export interface ValueProvider {
*/ */
export interface ClassProvider { 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; provide: any;
@ -134,7 +134,7 @@ export interface ClassProvider {
*/ */
export interface ExistingProvider { 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; provide: any;
@ -178,7 +178,7 @@ export interface ExistingProvider {
*/ */
export interface FactoryProvider { 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; provide: any;

View File

@ -6,19 +6,19 @@
* found in the LICENSE file at https://angular.io/license * 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. * @experimental i18n support is experimental.
*/ */
export const LOCALE_ID = new OpaqueToken('LocaleId'); export const LOCALE_ID = new InjectionToken<string>('LocaleId');
/** /**
* @experimental i18n support is experimental. * @experimental i18n support is experimental.
*/ */
export const TRANSLATIONS = new OpaqueToken('Translations'); export const TRANSLATIONS = new InjectionToken<string>('Translations');
/** /**
* @experimental i18n support is experimental. * @experimental i18n support is experimental.
*/ */
export const TRANSLATIONS_FORMAT = new OpaqueToken('TranslationsFormat'); export const TRANSLATIONS_FORMAT = new InjectionToken<string>('TranslationsFormat');

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {BaseError} from '../facade/errors';
import {stringify} from '../facade/lang'; import {stringify} from '../facade/lang';
import {ViewEncapsulation} from '../metadata'; import {ViewEncapsulation} from '../metadata';
@ -119,7 +119,7 @@ export type CompilerOptions = {
* *
* @experimental * @experimental
*/ */
export const COMPILER_OPTIONS = new OpaqueToken('compilerOptions'); export const COMPILER_OPTIONS = new InjectionToken<CompilerOptions[]>('compilerOptions');
/** /**
* A factory for creating a Compiler * A factory for creating a Compiler

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {Type} from '../type';
import {makeParamDecorator, makePropDecorator} from '../util/decorators'; import {makeParamDecorator, makePropDecorator} from '../util/decorators';
@ -44,7 +44,7 @@ import {makeParamDecorator, makePropDecorator} from '../util/decorators';
* *
* @experimental * @experimental
*/ */
export const ANALYZE_FOR_ENTRY_COMPONENTS = new OpaqueToken('AnalyzeForEntryComponents'); export const ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken<any>('AnalyzeForEntryComponents');
/** /**
* Type of the Attribute decorator / constructor function. * Type of the Attribute decorator / constructor function.

View File

@ -7,7 +7,7 @@
*/ */
import {CommonModule} from '@angular/common'; 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 {ChangeDetectionStrategy, ChangeDetectorRef, PipeTransform} from '@angular/core/src/change_detection/change_detection';
import {ComponentFactoryResolver} from '@angular/core/src/linker/component_factory_resolver'; import {ComponentFactoryResolver} from '@angular/core/src/linker/component_factory_resolver';
import {ElementRef} from '@angular/core/src/linker/element_ref'; 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 {EventEmitter} from '../../src/facade/async';
import {isBlank, isPresent, stringify} from '../../src/facade/lang'; import {isBlank, isPresent, stringify} from '../../src/facade/lang';
const ANCHOR_ELEMENT = new OpaqueToken('AnchorElement'); const ANCHOR_ELEMENT = new InjectionToken('AnchorElement');
export function main() { export function main() {
describe('jit', () => { declareTests({useJit: true}); }); describe('jit', () => { declareTests({useJit: true}); });

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {Console} from '@angular/core/src/console';
import {ComponentFixture, TestBed, inject} from '@angular/core/testing'; import {ComponentFixture, TestBed, inject} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
@ -30,6 +30,7 @@ class Dashboard {
class TurboEngine extends Engine {} class TurboEngine extends Engine {}
const CARS = new InjectionToken<Car[]>('Cars');
@Injectable() @Injectable()
class Car { class Car {
engine: Engine; engine: Engine;
@ -692,11 +693,11 @@ function declareTests({useJit}: {useJit: boolean}) {
it('should support multiProviders', () => { it('should support multiProviders', () => {
const injector = createInjector([ const injector = createInjector([
Engine, {provide: Car, useClass: SportsCar, multi: true}, Engine, {provide: CARS, useClass: SportsCar, multi: true},
{provide: Car, useClass: CarWithOptionalEngine, 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.length).toEqual(2);
expect(cars[0]).toBeAnInstanceOf(SportsCar); expect(cars[0]).toBeAnInstanceOf(SportsCar);
expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine); expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine);
@ -704,9 +705,9 @@ function declareTests({useJit}: {useJit: boolean}) {
it('should support multiProviders that are created using useExisting', () => { it('should support multiProviders that are created using useExisting', () => {
const injector = createInjector( 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.length).toEqual(1);
expect(cars[0]).toBe(injector.get(SportsCar)); expect(cars[0]).toBe(injector.get(SportsCar));
}); });

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {TestBed} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
@ -104,8 +104,8 @@ function declareTests({useJit}: {useJit: boolean}) {
return TestBed.createComponent(MyComp1).componentInstance.injector; return TestBed.createComponent(MyComp1).componentInstance.injector;
} }
it('should support providers with an OpaqueToken that contains a `.` in the name', () => { it('should support providers with an InjectionToken that contains a `.` in the name', () => {
const token = new OpaqueToken('a.b'); const token = new InjectionToken('a.b');
const tokenValue = 1; const tokenValue = 1;
const injector = createInjector([{provide: token, useValue: tokenValue}]); const injector = createInjector([{provide: token, useValue: tokenValue}]);
expect(injector.get(token)).toEqual(tokenValue); expect(injector.get(token)).toEqual(tokenValue);
@ -127,9 +127,9 @@ function declareTests({useJit}: {useJit: boolean}) {
expect(injector.get(token)).toEqual(tokenValue); expect(injector.get(token)).toEqual(tokenValue);
}); });
it('should support providers with an OpaqueToken that has a StringMap as value', () => { it('should support providers with an InjectionToken that has a StringMap as value', () => {
const token1 = new OpaqueToken('someToken'); const token1 = new InjectionToken('someToken');
const token2 = new OpaqueToken('someToken'); const token2 = new InjectionToken('someToken');
const tokenValue1 = {'a': 1}; const tokenValue1 = {'a': 1};
const tokenValue2 = {'a': 1}; const tokenValue2 = {'a': 1};
const injector = createInjector( const injector = createInjector(

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {AsyncTestCompleter} from './async_test_completer';
import {ComponentFixture} from './component_fixture'; import {ComponentFixture} from './component_fixture';
@ -30,12 +30,13 @@ let _nextRootElementId = 0;
/** /**
* @experimental * @experimental
*/ */
export const ComponentFixtureAutoDetect = new OpaqueToken('ComponentFixtureAutoDetect'); export const ComponentFixtureAutoDetect =
new InjectionToken<boolean[]>('ComponentFixtureAutoDetect');
/** /**
* @experimental * @experimental
*/ */
export const ComponentFixtureNoNgZone = new OpaqueToken('ComponentFixtureNoNgZone'); export const ComponentFixtureNoNgZone = new InjectionToken<boolean[]>('ComponentFixtureNoNgZone');
/** /**
* @experimental * @experimental

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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() { export function main() {
describe('injector metadata examples', () => { describe('injector metadata examples', () => {
@ -25,7 +25,17 @@ export function main() {
const injector = ReflectiveInjector.resolveAndCreate([]); const injector = ReflectiveInjector.resolveAndCreate([]);
expect(injector.get(Injector)).toBe(injector); expect(injector.get(Injector)).toBe(injector);
// #enddocregion // #enddocregion
});
it('should infer type', () => {
// #docregion InjectionToken
const BASE_URL = new InjectionToken<string>('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<string>`.
expect(url).toBe('http://localhost');
// #enddocregion
}); });
}); });
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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() { export function main() {
describe('Provider examples', () => { describe('Provider examples', () => {
@ -113,8 +113,8 @@ export function main() {
describe('FactoryProvider', () => { describe('FactoryProvider', () => {
it('works', () => { it('works', () => {
// #docregion FactoryProvider // #docregion FactoryProvider
const Location = new OpaqueToken('location'); const Location = new InjectionToken('location');
const Hash = new OpaqueToken('hash'); const Hash = new InjectionToken('hash');
const injector = ReflectiveInjector.resolveAndCreate([ const injector = ReflectiveInjector.resolveAndCreate([
{provide: Location, useValue: 'http://angular.io/#someLocation'}, { {provide: Location, useValue: 'http://angular.io/#someLocation'}, {
@ -130,8 +130,8 @@ export function main() {
it('supports optional dependencies', () => { it('supports optional dependencies', () => {
// #docregion FactoryProviderOptionalDeps // #docregion FactoryProviderOptionalDeps
const Location = new OpaqueToken('location'); const Location = new InjectionToken('location');
const Hash = new OpaqueToken('hash'); const Hash = new InjectionToken('hash');
const injector = ReflectiveInjector.resolveAndCreate([{ const injector = ReflectiveInjector.resolveAndCreate([{
provide: Hash, provide: Hash,

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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. * A bridge between a control and a native element.
@ -49,4 +49,4 @@ export interface ControlValueAccessor {
* See {@link DefaultValueAccessor} for how to implement one. * See {@link DefaultValueAccessor} for how to implement one.
* @stable * @stable
*/ */
export const NG_VALUE_ACCESSOR: OpaqueToken = new OpaqueToken('NgValueAccessor'); export const NG_VALUE_ACCESSOR = new InjectionToken<ControlValueAccessor>('NgValueAccessor');

View File

@ -116,12 +116,11 @@ function _throwError(dir: AbstractControlDirective, message: string): void {
throw new Error(`${message} ${messageEnd}`); throw new Error(`${message} ${messageEnd}`);
} }
export function composeValidators(validators: /* Array<Validator|Function> */ any[]): ValidatorFn { export function composeValidators(validators: Array<Validator|Function>): ValidatorFn {
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null; return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
} }
export function composeAsyncValidators(validators: /* Array<Validator|Function> */ any[]): export function composeAsyncValidators(validators: Array<Validator|Function>): AsyncValidatorFn {
AsyncValidatorFn {
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) : return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
null; null;
} }

View File

@ -6,9 +6,10 @@
* found in the LICENSE file at https://angular.io/license * 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 {toPromise} from 'rxjs/operator/toPromise';
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
import {AsyncValidatorFn, Validator, ValidatorFn} from './directives/validators';
import {StringMapWrapper} from './facade/collection'; import {StringMapWrapper} from './facade/collection';
import {isPresent} from './facade/lang'; import {isPresent} from './facade/lang';
import {AbstractControl} from './model'; 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'} * {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'}
* @stable * @stable
*/ */
export const NG_VALIDATORS: OpaqueToken = new OpaqueToken('NgValidators'); export const NG_VALIDATORS = new InjectionToken<Array<Validator|Function>>('NgValidators');
/** /**
* Providers for asynchronous validators to be used for {@link FormControl}s * Providers for asynchronous validators to be used for {@link FormControl}s
@ -41,7 +42,8 @@ export const NG_VALIDATORS: OpaqueToken = new OpaqueToken('NgValidators');
* *
* @stable * @stable
*/ */
export const NG_ASYNC_VALIDATORS: OpaqueToken = new OpaqueToken('NgAsyncValidators'); export const NG_ASYNC_VALIDATORS =
new InjectionToken<Array<Validator|Function>>('NgAsyncValidators');
/** /**
* Provides a set of validators used by form controls. * Provides a set of validators used by form controls.

View File

@ -42,8 +42,8 @@ export function main() {
http = injector.get(Http); http = injector.get(Http);
jsonp = injector.get(Jsonp); jsonp = injector.get(Jsonp);
jsonpBackend = injector.get(JSONPBackend); jsonpBackend = injector.get(JSONPBackend) as MockBackend;
xhrBackend = injector.get(XHRBackend); xhrBackend = injector.get(XHRBackend) as any as MockBackend;
let xhrCreatedConnections = 0; let xhrCreatedConnections = 0;
let jsonpCreatedConnections = 0; let jsonpCreatedConnections = 0;

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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. * 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 * @stable
*/ */
export const DOCUMENT: OpaqueToken = new OpaqueToken('DocumentToken'); export const DOCUMENT = new InjectionToken<Document>('DocumentToken');

View File

@ -6,13 +6,16 @@
* found in the LICENSE file at https://angular.io/license * 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'; import {getDOM} from '../dom_adapter';
/** /**
* @stable * @stable
*/ */
export const EVENT_MANAGER_PLUGINS: OpaqueToken = new OpaqueToken('EventManagerPlugins'); export const EVENT_MANAGER_PLUGINS =
new InjectionToken<EventManagerPlugin[]>('EventManagerPlugins');
/** /**
* @stable * @stable

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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'; import {EventManagerPlugin} from './event_manager';
const EVENT_NAMES = { const EVENT_NAMES = {
@ -53,7 +53,7 @@ const EVENT_NAMES = {
* *
* @experimental * @experimental
*/ */
export const HAMMER_GESTURE_CONFIG: OpaqueToken = new OpaqueToken('HammerGestureConfig'); export const HAMMER_GESTURE_CONFIG = new InjectionToken<HammerGestureConfig>('HammerGestureConfig');
export interface HammerInstance { export interface HammerInstance {
on(eventName: string, callback: Function): void; on(eventName: string, callback: Function): void;

View File

@ -6,6 +6,6 @@
* found in the LICENSE file at https://angular.io/license * 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');

View File

@ -7,11 +7,12 @@
*/ */
import {PlatformLocation} from '@angular/common'; 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'; import {WebWorkerPlatformLocation} from './platform_location';
/** /**
* Those providers should be added when the router is used in a worker context in addition to the * Those providers should be added when the router is used in a worker context in addition to the
* {@link ROUTER_PROVIDERS} and after them. * {@link ROUTER_PROVIDERS} and after them.

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {AnimationDriver, DOCUMENT, EVENT_MANAGER_PLUGINS, EventManager, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from '@angular/platform-browser';
import {APP_ID_RANDOM_PROVIDER} from './private_import_core'; 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'; import {MessageBasedRenderer} from './web_workers/ui/renderer';
/** /**
* Wrapper class that exposes the Worker * Wrapper class that exposes the Worker
* and underlying {@link MessageBus} for lower level message passing. * and underlying {@link MessageBus} for lower level message passing.
@ -42,7 +43,7 @@ export class WebWorkerInstance {
/** /**
* @experimental WebWorker support is currently experimental. * @experimental WebWorker support is currently experimental.
*/ */
export const WORKER_SCRIPT: OpaqueToken = new OpaqueToken('WebWorkerScript'); export const WORKER_SCRIPT = new InjectionToken<string>('WebWorkerScript');
/** /**
* A multi-provider used to automatically call the `start()` method after the service is * 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. * @experimental WebWorker support is currently experimental.
*/ */
export const WORKER_UI_STARTABLE_MESSAGING_SERVICE = export const WORKER_UI_STARTABLE_MESSAGING_SERVICE =
new OpaqueToken('WorkerRenderStartableMsgService'); new InjectionToken<MessageBasedRenderer[]>('WorkerRenderStartableMsgService');
export const _WORKER_UI_PLATFORM_PROVIDERS: Provider[] = [ export const _WORKER_UI_PLATFORM_PROVIDERS: Provider[] = [
{provide: NgZone, useFactory: createNgZone, deps: []}, {provide: NgZone, useFactory: createNgZone, deps: []},

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {Observable} from 'rxjs/Observable';
import {fromPromise} from 'rxjs/observable/fromPromise'; import {fromPromise} from 'rxjs/observable/fromPromise';
import {of } from 'rxjs/observable/of'; import {of } from 'rxjs/observable/of';
@ -16,10 +16,11 @@ import {mergeMap} from 'rxjs/operator/mergeMap';
import {LoadChildren, Route} from './config'; import {LoadChildren, Route} from './config';
import {flatten, wrapIntoObservable} from './utils/collection'; import {flatten, wrapIntoObservable} from './utils/collection';
/** /**
* @experimental * @experimental
*/ */
export const ROUTES = new OpaqueToken('ROUTES'); export const ROUTES = new InjectionToken<Route[][]>('ROUTES');
export class LoadedRouterConfig { export class LoadedRouterConfig {
constructor( constructor(

View File

@ -7,7 +7,7 @@
*/ */
import {APP_BASE_HREF, HashLocationStrategy, Location, LocationStrategy, PathLocationStrategy, PlatformLocation} from '@angular/common'; 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 {Route, Routes} from './config';
import {RouterLink, RouterLinkWithHref} from './directives/router_link'; 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. * @whatItDoes Is used in DI to configure the router.
* @stable * @stable
*/ */
export const ROUTER_CONFIGURATION = new OpaqueToken('ROUTER_CONFIGURATION'); export const ROUTER_CONFIGURATION = new InjectionToken<ExtraOptions>('ROUTER_CONFIGURATION');
/** /**
* @docsNotRequired * @docsNotRequired
*/ */
export const ROUTER_FORROOT_GUARD = new OpaqueToken('ROUTER_FORROOT_GUARD'); export const ROUTER_FORROOT_GUARD = new InjectionToken<void>('ROUTER_FORROOT_GUARD');
export const ROUTER_PROVIDERS: Provider[] = [ export const ROUTER_PROVIDERS: Provider[] = [
Location, Location,
@ -301,7 +301,8 @@ export function initialRouterNavigation(
* *
* @experimental * @experimental
*/ */
export const ROUTER_INITIALIZER = new OpaqueToken('Router Initializer'); export const ROUTER_INITIALIZER =
new InjectionToken<(compRef: ComponentRef<any>) => void>('Router Initializer');
export function provideRouterInitializer() { export function provideRouterInitializer() {
return [ return [

View File

@ -6,11 +6,12 @@
* found in the LICENSE file at https://angular.io/license * 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 {ExtraOptions, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, Router, RouterPreloader} from '@angular/router';
import {UpgradeModule} from '@angular/upgrade/static'; import {UpgradeModule} from '@angular/upgrade/static';
/** /**
* @whatItDoes Creates an initializer that in addition to setting up the Angular 2 * @whatItDoes Creates an initializer that in addition to setting up the Angular 2
* router sets up the ngRoute integration. * router sets up the ngRoute integration.
@ -57,7 +58,7 @@ export function initialRouterNavigation(
const router = ngUpgrade.injector.get(Router); const router = ngUpgrade.injector.get(Router);
const ref = ngUpgrade.injector.get(ApplicationRef); const ref = ngUpgrade.injector.get(ApplicationRef);
router.resetRootComponentType(ref.componentTypes[0]); (router as any).resetRootComponentType(ref.componentTypes[0]);
preloader.setUpPreloading(); preloader.setUpPreloading();
if (opts.initialNavigation === false) { if (opts.initialNavigation === false) {
router.setUpLocationChangeListener(); router.setUpLocationChangeListener();
@ -86,4 +87,4 @@ export function setUpLocationSync(ngUpgrade: UpgradeModule): void {
url.href = next; url.href = next;
router.navigateByUrl(url.pathname); router.navigateByUrl(url.pathname);
}); });
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * 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 {async} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser'; import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
@ -23,7 +23,7 @@ export function main() {
it('should downgrade ng2 service to ng1', async(() => { it('should downgrade ng2 service to ng1', async(() => {
// Tokens used in ng2 to identify services // Tokens used in ng2 to identify services
const Ng2Service = new OpaqueToken('ng2-service'); const Ng2Service = new InjectionToken('ng2-service');
// Sample ng1 NgModule for tests // Sample ng1 NgModule for tests
@NgModule({ @NgModule({
@ -49,7 +49,7 @@ export function main() {
it('should upgrade ng1 service to ng2', async(() => { it('should upgrade ng1 service to ng2', async(() => {
// Tokens used in ng2 to identify services // Tokens used in ng2 to identify services
const Ng1Service = new OpaqueToken('ng1-service'); const Ng1Service = new InjectionToken('ng1-service');
// Sample ng1 NgModule for tests // Sample ng1 NgModule for tests
@NgModule({ @NgModule({

View File

@ -45,7 +45,7 @@ function routerFactory($q, $location, $browser, $rootScope, $injector, $routerRo
var exports = { var exports = {
Injectable: function () {}, Injectable: function () {},
OpaqueToken: function () {}, InjectionToken: function () {},
Inject: function () {} Inject: function () {}
}; };
var routerRequire = function () {return exports;}; var routerRequire = function () {return exports;};

View File

@ -1,5 +1,5 @@
/** @stable */ /** @stable */
export declare const APP_BASE_HREF: OpaqueToken; export declare const APP_BASE_HREF: InjectionToken<string>;
/** @stable */ /** @stable */
export declare class AsyncPipe implements OnDestroy { export declare class AsyncPipe implements OnDestroy {

View File

@ -19,7 +19,7 @@ export declare abstract class AfterViewInit {
} }
/** @experimental */ /** @experimental */
export declare const ANALYZE_FOR_ENTRY_COMPONENTS: OpaqueToken; export declare const ANALYZE_FOR_ENTRY_COMPONENTS: InjectionToken<any>;
/** @experimental */ /** @experimental */
export declare function animate(timing: string | number, styles?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata): AnimationAnimateMetadata; export declare function animate(timing: string | number, styles?: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata): AnimationAnimateMetadata;
@ -131,13 +131,13 @@ export declare abstract class AnimationWithStepsMetadata extends AnimationMetada
} }
/** @experimental */ /** @experimental */
export declare const APP_BOOTSTRAP_LISTENER: OpaqueToken; export declare const APP_BOOTSTRAP_LISTENER: InjectionToken<((compRef: ComponentRef<any>) => void)[]>;
/** @experimental */ /** @experimental */
export declare const APP_ID: any; export declare const APP_ID: InjectionToken<string>;
/** @experimental */ /** @experimental */
export declare const APP_INITIALIZER: any; export declare const APP_INITIALIZER: InjectionToken<(() => void)[]>;
/** @experimental */ /** @experimental */
export declare class ApplicationInitStatus { export declare class ApplicationInitStatus {
@ -221,7 +221,12 @@ export declare class Compiler {
} }
/** @experimental */ /** @experimental */
export declare const COMPILER_OPTIONS: OpaqueToken; export declare const COMPILER_OPTIONS: InjectionToken<{
useDebug?: boolean;
useJit?: boolean;
defaultEncapsulation?: ViewEncapsulation;
providers?: any[];
}[]>;
/** @experimental */ /** @experimental */
export declare abstract class CompilerFactory { export declare abstract class CompilerFactory {
@ -491,9 +496,16 @@ export interface InjectDecorator {
new (token: any): Inject; new (token: any): Inject;
} }
/** @stable */
export declare class InjectionToken<T> extends OpaqueToken {
constructor(desc: string);
toString(): string;
}
/** @stable */ /** @stable */
export declare abstract class Injector { export declare abstract class Injector {
get(token: any, notFoundValue?: any): any; get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T): T;
/** @deprecated */ get(token: any, notFoundValue?: any): any;
static NULL: Injector; static NULL: Injector;
static THROW_IF_NOT_FOUND: Object; static THROW_IF_NOT_FOUND: Object;
} }
@ -586,7 +598,7 @@ export declare class KeyValueDiffers {
} }
/** @experimental */ /** @experimental */
export declare const LOCALE_ID: OpaqueToken; export declare const LOCALE_ID: InjectionToken<string>;
/** @experimental */ /** @experimental */
export declare class ModuleWithComponentFactories<T> { export declare class ModuleWithComponentFactories<T> {
@ -672,8 +684,9 @@ export declare abstract class OnInit {
abstract ngOnInit(): void; abstract ngOnInit(): void;
} }
/** @stable */ /** @deprecated */
export declare class OpaqueToken { export declare class OpaqueToken {
protected _desc: string;
constructor(_desc: string); constructor(_desc: string);
toString(): string; toString(): string;
} }
@ -691,7 +704,7 @@ export interface OptionalDecorator {
export declare const Output: OutputDecorator; export declare const Output: OutputDecorator;
/** @experimental */ /** @experimental */
export declare const PACKAGE_ROOT_URL: any; export declare const PACKAGE_ROOT_URL: InjectionToken<string>;
/** @stable */ /** @stable */
export declare const Pipe: PipeDecorator; export declare const Pipe: PipeDecorator;
@ -702,7 +715,7 @@ export interface PipeTransform {
} }
/** @experimental */ /** @experimental */
export declare const PLATFORM_INITIALIZER: any; export declare const PLATFORM_INITIALIZER: InjectionToken<(() => void)[]>;
/** @experimental */ /** @experimental */
export declare const platformCore: (extraProviders?: Provider[]) => PlatformRef; 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; export declare function transition(stateChangeExpr: string | ((fromState: string, toState: string) => boolean), steps: AnimationMetadata | AnimationMetadata[]): AnimationStateTransitionMetadata;
/** @experimental */ /** @experimental */
export declare const TRANSLATIONS: OpaqueToken; export declare const TRANSLATIONS: InjectionToken<string>;
/** @experimental */ /** @experimental */
export declare const TRANSLATIONS_FORMAT: OpaqueToken; export declare const TRANSLATIONS_FORMAT: InjectionToken<string>;
/** @experimental */ /** @experimental */
export declare function trigger(name: string, animation: AnimationMetadata[]): AnimationEntryMetadata; export declare function trigger(name: string, animation: AnimationMetadata[]): AnimationEntryMetadata;

View File

@ -20,10 +20,10 @@ export declare class ComponentFixture<T> {
} }
/** @experimental */ /** @experimental */
export declare const ComponentFixtureAutoDetect: OpaqueToken; export declare const ComponentFixtureAutoDetect: InjectionToken<boolean[]>;
/** @experimental */ /** @experimental */
export declare const ComponentFixtureNoNgZone: OpaqueToken; export declare const ComponentFixtureNoNgZone: InjectionToken<boolean[]>;
/** @experimental */ /** @experimental */
export declare function discardPeriodicTasks(): void; export declare function discardPeriodicTasks(): void;

View File

@ -355,13 +355,13 @@ export declare class MinLengthValidator implements Validator, OnChanges {
} }
/** @stable */ /** @stable */
export declare const NG_ASYNC_VALIDATORS: OpaqueToken; export declare const NG_ASYNC_VALIDATORS: InjectionToken<(Function | Validator)[]>;
/** @stable */ /** @stable */
export declare const NG_VALIDATORS: OpaqueToken; export declare const NG_VALIDATORS: InjectionToken<(Function | Validator)[]>;
/** @stable */ /** @stable */
export declare const NG_VALUE_ACCESSOR: OpaqueToken; export declare const NG_VALUE_ACCESSOR: InjectionToken<ControlValueAccessor>;
/** @stable */ /** @stable */
export declare abstract class NgControl extends AbstractControlDirective { export declare abstract class NgControl extends AbstractControlDirective {

View File

@ -20,7 +20,7 @@ export declare class By {
export declare function disableDebugTools(): void; export declare function disableDebugTools(): void;
/** @stable */ /** @stable */
export declare const DOCUMENT: OpaqueToken; export declare const DOCUMENT: InjectionToken<Document>;
/** @stable */ /** @stable */
export declare abstract class DomSanitizer implements Sanitizer { export declare abstract class DomSanitizer implements Sanitizer {
@ -36,7 +36,7 @@ export declare abstract class DomSanitizer implements Sanitizer {
export declare function enableDebugTools<T>(ref: ComponentRef<T>): ComponentRef<T>; export declare function enableDebugTools<T>(ref: ComponentRef<T>): ComponentRef<T>;
/** @stable */ /** @stable */
export declare const EVENT_MANAGER_PLUGINS: OpaqueToken; export declare const EVENT_MANAGER_PLUGINS: InjectionToken<EventManagerPlugin[]>;
/** @stable */ /** @stable */
export declare class EventManager { export declare class EventManager {
@ -47,7 +47,7 @@ export declare class EventManager {
} }
/** @experimental */ /** @experimental */
export declare const HAMMER_GESTURE_CONFIG: OpaqueToken; export declare const HAMMER_GESTURE_CONFIG: InjectionToken<HammerGestureConfig>;
/** @experimental */ /** @experimental */
export declare class HammerGestureConfig { export declare class HammerGestureConfig {

View File

@ -85,7 +85,7 @@ export declare const WORKER_APP_LOCATION_PROVIDERS: ({
provide: typeof PlatformLocation; provide: typeof PlatformLocation;
useClass: typeof WebWorkerPlatformLocation; useClass: typeof WebWorkerPlatformLocation;
} | { } | {
provide: any; provide: InjectionToken<(() => void)[]>;
useFactory: (platformLocation: WebWorkerPlatformLocation, zone: NgZone) => () => Promise<boolean>; useFactory: (platformLocation: WebWorkerPlatformLocation, zone: NgZone) => () => Promise<boolean>;
multi: boolean; multi: boolean;
deps: (typeof NgZone | typeof PlatformLocation)[]; deps: (typeof NgZone | typeof PlatformLocation)[];

View File

@ -223,10 +223,10 @@ export declare class Router {
} }
/** @stable */ /** @stable */
export declare const ROUTER_CONFIGURATION: OpaqueToken; export declare const ROUTER_CONFIGURATION: InjectionToken<ExtraOptions>;
/** @experimental */ /** @experimental */
export declare const ROUTER_INITIALIZER: OpaqueToken; export declare const ROUTER_INITIALIZER: InjectionToken<(compRef: ComponentRef<any>) => void>;
/** @experimental */ /** @experimental */
export declare abstract class RouteReuseStrategy { export declare abstract class RouteReuseStrategy {