Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions packages/core/src/di/forward_ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import {stringify} from '../util';


/**
* An interface that a function passed into {@link forwardRef} has to implement.
* An interface that a function passed into {@link resolveForwardRef} has to implement.
*
* ### Example
*
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref_fn'}
* @experimental
*/
export interface ForwardRefFn { (): any; }
export interface ForwardRefFn<T> {
(): T;
__forward_ref__: Function;
}


/**
* Allows to refer to references which are not yet defined.
Expand All @@ -33,10 +34,11 @@ export interface ForwardRefFn { (): any; }
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
* @experimental
*/
export function forwardRef(forwardRefFn: ForwardRefFn): Type<any> {
(<any>forwardRefFn).__forward_ref__ = forwardRef;
(<any>forwardRefFn).toString = function() { return stringify(this()); };
return (<Type<any>><any>forwardRefFn);
export function forwardRef<T>(typeFactory: () => T): ForwardRefFn<T> {
const forwardRefFn = <ForwardRefFn<T>>typeFactory;
forwardRefFn.__forward_ref__ = forwardRef;
forwardRefFn.toString = function() { return stringify(this()); };
return forwardRefFn;
}

/**
Expand All @@ -51,11 +53,10 @@ export function forwardRef(forwardRefFn: ForwardRefFn): Type<any> {
* See: {@link forwardRef}
* @experimental
*/
export function resolveForwardRef(type: any): any {
if (typeof type === 'function' && type.hasOwnProperty('__forward_ref__') &&
type.__forward_ref__ === forwardRef) {
return (<ForwardRefFn>type)();
} else {
return type;
}
export function resolveForwardRef<T>(type: T | ForwardRefFn<T>): T {
return _isForwardRefFn(type) ? type() : type;
}

function _isForwardRefFn<T>(t: any): t is ForwardRefFn<T> {
return typeof t === 'function' && t.__forward_ref__ === forwardRef;
}
7 changes: 4 additions & 3 deletions packages/core/src/di/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import {Type} from '../type';
import {ForwardRefFn} from './forward_ref';

/**
* @whatItDoes Configures the {@link Injector} to return an instance of `Type` when `Type' is used
Expand Down Expand Up @@ -103,7 +104,7 @@ export interface ClassProvider {
/**
* Class to instantiate for the `token`.
*/
useClass: Type<any>;
useClass: Type<any>|ForwardRefFn<any>;

/**
* If true, then injector returns an array of instances. This is useful to allow multiple
Expand Down Expand Up @@ -216,5 +217,5 @@ export interface FactoryProvider {
*
* @stable
*/
export type Provider =
TypeProvider | ValueProvider | ClassProvider | ExistingProvider | FactoryProvider | any[];
export type Provider = TypeProvider | ValueProvider | ClassProvider | ExistingProvider |
FactoryProvider | ForwardRefFn<any>| any[];
11 changes: 6 additions & 5 deletions packages/core/src/metadata/ng_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
* found in the LICENSE file at https://angular.io/license
*/

import {Provider} from '../di';
import {ForwardRefFn, Provider} from '../di';
import {Type} from '../type';
import {TypeDecorator, makeDecorator} from '../util/decorators';


/**
* A wrapper around a module that also includes the providers.
*
Expand Down Expand Up @@ -112,7 +113,7 @@ export interface NgModule {
* }
* ```
*/
declarations?: Array<Type<any>|any[]>;
declarations?: Array<Type<any>|ForwardRefFn<any>|any[]>;

/**
* Specifies a list of modules whose exported directives/pipes
Expand All @@ -129,7 +130,7 @@ export interface NgModule {
* }
* ```
*/
imports?: Array<Type<any>|ModuleWithProviders|any[]>;
imports?: Array<Type<any>|ModuleWithProviders|ForwardRefFn<any>|any[]>;

/**
* Specifies a list of directives/pipes/modules that can be used within the template
Expand All @@ -146,7 +147,7 @@ export interface NgModule {
* }
* ```
*/
exports?: Array<Type<any>|any[]>;
exports?: Array<Type<any>|ForwardRefFn<any>|any[]>;

/**
* Specifies a list of components that should be compiled when this module is defined.
Expand Down Expand Up @@ -191,4 +192,4 @@ export interface NgModule {
* @Annotation
*/
export const NgModule: NgModuleDecorator =
<NgModuleDecorator>makeDecorator('NgModule', (ngModule: NgModule) => ngModule);
<NgModuleDecorator>makeDecorator('NgModule', (ngModule: NgModule) => ngModule);
6 changes: 4 additions & 2 deletions packages/upgrade/src/dynamic/upgrade_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {Compiler, CompilerOptions, Directive, Injector, NgModule, NgModuleRef, NgZone, Provider, Testability, Type} from '@angular/core';
import {Compiler, CompilerOptions, Directive, ForwardRefFn, Injector, NgModule, NgModuleRef, NgZone, Provider, Testability, Type} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

import * as angular from '../common/angular1';
Expand Down Expand Up @@ -116,7 +116,9 @@ export class UpgradeAdapter {
private moduleRef: NgModuleRef<any>|null = null;
private ng2BootstrapDeferred: Deferred<angular.IInjectorService>;

constructor(private ng2AppModule: Type<any>, private compilerOptions?: CompilerOptions) {
constructor(
private ng2AppModule: Type<any>|ForwardRefFn<Type<any>>,
private compilerOptions?: CompilerOptions) {
if (!ng2AppModule) {
throw new Error(
'UpgradeAdapter cannot be instantiated without an NgModule of the Angular app.');
Expand Down
13 changes: 7 additions & 6 deletions tools/public_api_guard/core/core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export declare type ClassDefinition = {
export interface ClassProvider {
multi?: boolean;
provide: any;
useClass: Type<any>;
useClass: Type<any> | ForwardRefFn<any>;
}

/** @deprecated */
Expand Down Expand Up @@ -421,11 +421,12 @@ export interface FactoryProvider {
}

/** @experimental */
export declare function forwardRef(forwardRefFn: ForwardRefFn): Type<any>;
export declare function forwardRef<T>(typeFactory: () => T): ForwardRefFn<T>;

/** @experimental */
export interface ForwardRefFn {
(): any;
export interface ForwardRefFn<T> {
__forward_ref__: Function;
(): T;
}

/** @experimental */
Expand Down Expand Up @@ -731,7 +732,7 @@ export interface Predicate<T> {
}

/** @stable */
export declare type Provider = TypeProvider | ValueProvider | ClassProvider | ExistingProvider | FactoryProvider | any[];
export declare type Provider = TypeProvider | ValueProvider | ClassProvider | ExistingProvider | FactoryProvider | ForwardRefFn<any> | any[];

/** @stable */
export declare abstract class Query {
Expand Down Expand Up @@ -882,7 +883,7 @@ export interface ResolvedReflectiveProvider {
}

/** @experimental */
export declare function resolveForwardRef(type: any): any;
export declare function resolveForwardRef<T>(type: T | ForwardRefFn<T>): T;

/** @deprecated */
export declare abstract class RootRenderer {
Expand Down
2 changes: 1 addition & 1 deletion tools/public_api_guard/upgrade/upgrade.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @stable */
export declare class UpgradeAdapter {
constructor(ng2AppModule: Type<any>, compilerOptions?: CompilerOptions);
constructor(ng2AppModule: Type<any> | ForwardRefFn<Type<any>>, compilerOptions?: CompilerOptions);
bootstrap(element: Element, modules?: any[], config?: angular.IAngularBootstrapConfig): UpgradeAdapterRef;
downgradeNg2Component(component: Type<any>): Function;
downgradeNg2Provider(token: any): Function;
Expand Down