refactor(ivy): make return value of define(Component|Directive|Pipe|Injector|Injectable) private (#23371) (#23383)

Ivy definition looks something like this:

```
class MyService {
  static ngInjectableDef = defineInjectable({
    …
  });
}
```

Here the argument to `defineInjectable` is well known public contract which needs
to be honored in backward compatible way between versions. The type of the
return value of `defineInjectable` on the other hand is private and can change
shape drastically between versions without effecting backwards compatibility of
libraries publish to NPM. To our users it is effectively an opaque token.
For this reson why declare the return value of `defineInjectable` as `never`.

PR Close #23383
This commit is contained in:
Misko Hevery 2018-04-14 09:18:38 -07:00 committed by Igor Minar
parent 815ae29b83
commit b64a276d4b
21 changed files with 105 additions and 96 deletions

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 {InjectableDef, defineInjectable} from '../../di/defs'; import {defineInjectable} from '../../di/defs';
import {Optional, SkipSelf} from '../../di/metadata'; import {Optional, SkipSelf} from '../../di/metadata';
import {StaticProvider} from '../../di/provider'; import {StaticProvider} from '../../di/provider';
import {DefaultIterableDifferFactory} from '../differs/default_iterable_differ'; import {DefaultIterableDifferFactory} from '../differs/default_iterable_differ';
@ -137,7 +137,7 @@ export interface IterableDifferFactory {
* *
*/ */
export class IterableDiffers { export class IterableDiffers {
static ngInjectableDef: InjectableDef<IterableDiffers> = defineInjectable({ static ngInjectableDef = defineInjectable({
providedIn: 'root', providedIn: 'root',
factory: () => new IterableDiffers([new DefaultIterableDifferFactory()]) factory: () => new IterableDiffers([new DefaultIterableDifferFactory()])
}); });

View File

@ -13,7 +13,7 @@
*/ */
export * from './di/metadata'; export * from './di/metadata';
export * from './di/defs'; export {InjectableType, InjectorType, defineInjectable, defineInjector} from './di/defs';
export {forwardRef, resolveForwardRef, ForwardRefFn} from './di/forward_ref'; export {forwardRef, resolveForwardRef, ForwardRefFn} from './di/forward_ref';
export {Injectable, InjectableDecorator, InjectableProvider} from './di/injectable'; export {Injectable, InjectableDecorator, InjectableProvider} from './di/injectable';
export {inject, InjectFlags, INJECTOR, Injector} from './di/injector'; export {inject, InjectFlags, INJECTOR, Injector} from './di/injector';

View File

@ -20,9 +20,7 @@ import {ClassProvider, ClassSansProvider, ConstructorProvider, ConstructorSansPr
* `InjectorDef`, `NgModule`, or a special scope (e.g. `'root'`). A value of `null` indicates * `InjectorDef`, `NgModule`, or a special scope (e.g. `'root'`). A value of `null` indicates
* that the injectable does not belong to any scope. * that the injectable does not belong to any scope.
* *
* This type is typically generated by the Angular compiler, but can be hand-written if needed. * NOTE: This is a private type and should not be exported
*
* @experimental
*/ */
export interface InjectableDef<T> { export interface InjectableDef<T> {
/** /**
@ -54,7 +52,7 @@ export interface InjectableDef<T> {
* structure of providers with a defined priority (identically to how `NgModule`s also have * structure of providers with a defined priority (identically to how `NgModule`s also have
* an import/dependency structure). * an import/dependency structure).
* *
* @experimental * NOTE: This is a private type and should not be exported
*/ */
export interface InjectorDef<T> { export interface InjectorDef<T> {
factory: () => T; factory: () => T;
@ -75,7 +73,12 @@ export interface InjectorDef<T> {
* *
* @experimental * @experimental
*/ */
export interface InjectableType<T> extends Type<T> { ngInjectableDef: InjectableDef<T>; } export interface InjectableType<T> extends Type<T> {
/**
* Opaque type whose structure is highly version dependent. Do not rely on any properties.
*/
ngInjectableDef: never;
}
/** /**
* A type which has an `InjectorDef` static field. * A type which has an `InjectorDef` static field.
@ -84,7 +87,12 @@ export interface InjectableType<T> extends Type<T> { ngInjectableDef: Injectable
* *
* @experimental * @experimental
*/ */
export interface InjectorType<T> extends Type<T> { ngInjectorDef: InjectorDef<T>; } export interface InjectorType<T> extends Type<T> {
/**
* Opaque type whose structure is highly version dependent. Do not rely on any properties.
*/
ngInjectorDef: never;
}
/** /**
* Describes the `InjectorDef` equivalent of a `ModuleWithProviders`, an `InjectorDefType` with an * Describes the `InjectorDef` equivalent of a `ModuleWithProviders`, an `InjectorDefType` with an
@ -92,7 +100,7 @@ export interface InjectorType<T> extends Type<T> { ngInjectorDef: InjectorDef<T>
* *
* Objects of this type can be listed in the imports section of an `InjectorDef`. * Objects of this type can be listed in the imports section of an `InjectorDef`.
* *
* @experimental * NOTE: This is a private type and should not be exported
*/ */
export interface InjectorTypeWithProviders<T> { export interface InjectorTypeWithProviders<T> {
ngModule: InjectorType<T>; ngModule: InjectorType<T>;
@ -120,12 +128,10 @@ export interface InjectorTypeWithProviders<T> {
export function defineInjectable<T>(opts: { export function defineInjectable<T>(opts: {
providedIn?: Type<any>| 'root' | 'any' | null, providedIn?: Type<any>| 'root' | 'any' | null,
factory: () => T, factory: () => T,
}): InjectableDef<T> { }): never {
return { return ({
providedIn: opts.providedIn as any || null, providedIn: opts.providedIn as any || null, factory: opts.factory, value: undefined,
factory: opts.factory, } as InjectableDef<T>) as never;
value: undefined,
};
} }
/** /**
@ -149,10 +155,8 @@ export function defineInjectable<T>(opts: {
* @experimental * @experimental
*/ */
export function defineInjector(options: {factory: () => any, providers?: any[], imports?: any[]}): export function defineInjector(options: {factory: () => any, providers?: any[], imports?: any[]}):
InjectorDef<any> { never {
return { return ({
factory: options.factory, factory: options.factory, providers: options.providers || [], imports: options.imports || [],
providers: options.providers || [], } as InjectorDef<any>) as never;
imports: options.imports || [],
};
} }

View File

@ -52,7 +52,7 @@ export class InjectionToken<T> {
/** @internal */ /** @internal */
readonly ngMetadataName = 'InjectionToken'; readonly ngMetadataName = 'InjectionToken';
readonly ngInjectableDef: InjectableDef<T>|undefined; readonly ngInjectableDef: never|undefined;
constructor(protected _desc: string, options?: { constructor(protected _desc: string, options?: {
providedIn?: Type<any>| 'root' | null, providedIn?: Type<any>| 'root' | null,
@ -71,6 +71,4 @@ export class InjectionToken<T> {
toString(): string { return `InjectionToken ${this._desc}`; } toString(): string { return `InjectionToken ${this._desc}`; }
} }
export interface InjectableDefToken<T> extends InjectionToken<T> { export interface InjectableDefToken<T> extends InjectionToken<T> { ngInjectableDef: never; }
ngInjectableDef: InjectableDef<T>;
}

View File

@ -326,7 +326,7 @@ export class R3Injector {
} }
function injectableDefRecord(token: Type<any>| InjectionToken<any>): Record<any> { function injectableDefRecord(token: Type<any>| InjectionToken<any>): Record<any> {
const def = (token as InjectableType<any>).ngInjectableDef; const def = (token as InjectableType<any>).ngInjectableDef as InjectableDef<any>;
if (def === undefined) { if (def === undefined) {
throw new Error(`Type ${stringify(token)} is missing an ngInjectableDef definition.`); throw new Error(`Type ${stringify(token)} is missing an ngInjectableDef definition.`);
} }

View File

@ -162,7 +162,7 @@ export function defineComponent<T>(componentDefinition: {
* `PipeDefs`s. The function is necessary to be able to support forward declarations. * `PipeDefs`s. The function is necessary to be able to support forward declarations.
*/ */
pipes?: PipeTypesOrFactory | null; pipes?: PipeTypesOrFactory | null;
}): ComponentDef<T> { }): never {
const type = componentDefinition.type; const type = componentDefinition.type;
const pipeTypes = componentDefinition.pipes !; const pipeTypes = componentDefinition.pipes !;
const directiveTypes = componentDefinition.directives !; const directiveTypes = componentDefinition.directives !;
@ -196,7 +196,7 @@ export function defineComponent<T>(componentDefinition: {
}; };
const feature = componentDefinition.features; const feature = componentDefinition.features;
feature && feature.forEach((fn) => fn(def)); feature && feature.forEach((fn) => fn(def));
return def; return def as never;
} }
export function extractDirectiveDef(type: DirectiveType<any>& ComponentType<any>): export function extractDirectiveDef(type: DirectiveType<any>& ComponentType<any>):
@ -400,7 +400,7 @@ export const defineDirective = defineComponent as any as<T>(directiveDefinition:
* See: {@link Directive.exportAs} * See: {@link Directive.exportAs}
*/ */
exportAs?: string; exportAs?: string;
}) => DirectiveDef<T>; }) => never;
/** /**
* Create a pipe definition object. * Create a pipe definition object.
@ -428,11 +428,11 @@ export function definePipe<T>(pipeDef: {
/** Whether the pipe is pure. */ /** Whether the pipe is pure. */
pure?: boolean pure?: boolean
}): PipeDef<T> { }): never {
return <PipeDef<T>>{ return (<PipeDef<T>>{
name: pipeDef.name, name: pipeDef.name,
n: pipeDef.factory, n: pipeDef.factory,
pure: pipeDef.pure !== false, pure: pipeDef.pure !== false,
onDestroy: pipeDef.type.prototype.ngOnDestroy || null onDestroy: pipeDef.type.prototype.ngOnDestroy || null
}; }) as never;
} }

View File

@ -38,13 +38,13 @@ export const enum RenderFlags {
* A subclass of `Type` which has a static `ngComponentDef`:`ComponentDef` field making it * A subclass of `Type` which has a static `ngComponentDef`:`ComponentDef` field making it
* consumable for rendering. * consumable for rendering.
*/ */
export interface ComponentType<T> extends Type<T> { ngComponentDef: ComponentDef<T>; } export interface ComponentType<T> extends Type<T> { ngComponentDef: never; }
/** /**
* A subclass of `Type` which has a static `ngDirectiveDef`:`DirectiveDef` field making it * A subclass of `Type` which has a static `ngDirectiveDef`:`DirectiveDef` field making it
* consumable for rendering. * consumable for rendering.
*/ */
export interface DirectiveType<T> extends Type<T> { ngDirectiveDef: DirectiveDef<T>; } export interface DirectiveType<T> extends Type<T> { ngDirectiveDef: never; }
export const enum DirectiveDefFlags {ContentQuery = 0b10} export const enum DirectiveDefFlags {ContentQuery = 0b10}
@ -52,7 +52,7 @@ export const enum DirectiveDefFlags {ContentQuery = 0b10}
* A subclass of `Type` which has a static `ngPipeDef`:`PipeDef` field making it * A subclass of `Type` which has a static `ngPipeDef`:`PipeDef` field making it
* consumable for rendering. * consumable for rendering.
*/ */
export interface PipeType<T> extends Type<T> { ngPipeDef: PipeDef<T>; } export interface PipeType<T> extends Type<T> { ngPipeDef: never; }
/** /**
* Runtime link information for Directives. * Runtime link information for Directives.

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 {InjectableDef, Injector, InjectorDef, createInjector, defineInjectable, defineInjector} from '@angular/core'; import {Injector, createInjector, defineInjectable, defineInjector} from '@angular/core';
export class RootService { export class RootService {
static ngInjectableDef = defineInjectable({ static ngInjectableDef = defineInjectable({

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 {Component, ContentChild, Directive, Injectable, Injector, InjectorDef, Input, NgModule, NgModuleFactory, NgModuleRef, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, defineInjector} from '../../../src/core'; import {Component, ContentChild, Directive, Injectable, Injector, Input, NgModule, NgModuleFactory, NgModuleRef, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, defineInjector} from '../../../src/core';
import * as r3 from '../../../src/render3/index'; import * as r3 from '../../../src/render3/index';
const details_elided = { const details_elided = {

View File

@ -8,8 +8,11 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core'; import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
import * as $r3$ from '../../../src/core_render3_private_export'; import * as $r3$ from '../../../src/core_render3_private_export';
import {ComponentDef} from '../../../src/render3/interfaces/definition';
import {renderComponent, toHtml} from '../render_util'; import {renderComponent, toHtml} from '../render_util';
/// See: `normative.md` /// See: `normative.md`
describe('components & directives', () => { describe('components & directives', () => {
type $RenderFlags$ = $r3$.ɵRenderFlags; type $RenderFlags$ = $r3$.ɵRenderFlags;
@ -76,8 +79,8 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyComponent.ngComponentDef.directiveDefs = (MyComponent.ngComponentDef as ComponentDef<any>).directiveDefs =
[ChildComponent.ngComponentDef, SomeDirective.ngDirectiveDef]; [(ChildComponent.ngComponentDef as ComponentDef<any>), SomeDirective.ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyComponent)).toEqual('<child some-directive="">child-view</child>!'); expect(renderComp(MyComponent)).toEqual('<child some-directive="">child-view</child>!');
@ -126,7 +129,7 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [HostBindingDir.ngDirectiveDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs = [HostBindingDir.ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<div hostbindingdir="" id="some id"></div>`); expect(renderComp(MyApp)).toEqual(`<div hostbindingdir="" id="some id"></div>`);
@ -177,7 +180,7 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [HostListenerDir.ngDirectiveDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs = [HostListenerDir.ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<button hostlistenerdir="">Click</button>`); expect(renderComp(MyApp)).toEqual(`<button hostlistenerdir="">Click</button>`);
@ -222,7 +225,7 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [HostAttributeDir.ngDirectiveDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs = [HostAttributeDir.ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<div hostattributedir="" role="listbox"></div>`); expect(renderComp(MyApp)).toEqual(`<div hostattributedir="" role="listbox"></div>`);
@ -270,7 +273,7 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [HostBindingDir.ngDirectiveDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs = [HostBindingDir.ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<div aria-label="some label" hostbindingdir=""></div>`); expect(renderComp(MyApp)).toEqual(`<div aria-label="some label" hostbindingdir=""></div>`);
@ -333,7 +336,8 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [MyComp.ngComponentDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs =
[(MyComp.ngComponentDef as ComponentDef<any>)];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<my-comp>some name</my-comp>`); expect(renderComp(MyApp)).toEqual(`<my-comp>some name</my-comp>`);
@ -463,7 +467,8 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [MyArrayComp.ngComponentDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs =
[(MyArrayComp.ngComponentDef as ComponentDef<any>)];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<my-array-comp>Nancy Bess</my-array-comp>`); expect(renderComp(MyApp)).toEqual(`<my-array-comp>Nancy Bess</my-array-comp>`);
@ -507,7 +512,8 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [MyArrayComp.ngComponentDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs =
[(MyArrayComp.ngComponentDef as ComponentDef<any>)];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<my-array-comp>NANCY Bess</my-array-comp>`); expect(renderComp(MyApp)).toEqual(`<my-array-comp>NANCY Bess</my-array-comp>`);
@ -567,7 +573,8 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [MyComp.ngComponentDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs =
[(MyComp.ngComponentDef as ComponentDef<any>)];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<my-comp>3</my-comp>`); expect(renderComp(MyApp)).toEqual(`<my-comp>3</my-comp>`);
@ -609,7 +616,8 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [MyArrayComp.ngComponentDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs =
[(MyArrayComp.ngComponentDef as ComponentDef<any>)];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<my-array-comp>Nancy Bess</my-array-comp>`); expect(renderComp(MyApp)).toEqual(`<my-array-comp>Nancy Bess</my-array-comp>`);
@ -721,7 +729,8 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [MyComp.ngComponentDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs =
[(MyComp.ngComponentDef as ComponentDef<any>)];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<my-comp>start-abcde-middle-fghi-end</my-comp>`); expect(renderComp(MyApp)).toEqual(`<my-comp>start-abcde-middle-fghi-end</my-comp>`);
@ -795,7 +804,8 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [ObjectComp.ngComponentDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs =
[(ObjectComp.ngComponentDef as ComponentDef<any>)];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)).toEqual(`<object-comp><p>500</p><p>slide</p></object-comp>`); expect(renderComp(MyApp)).toEqual(`<object-comp><p>500</p><p>slide</p></object-comp>`);
@ -882,7 +892,8 @@ describe('components & directives', () => {
} }
// NON-NORMATIVE (done by defineNgModule) // NON-NORMATIVE (done by defineNgModule)
MyApp.ngComponentDef.directiveDefs = [NestedComp.ngComponentDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs =
[(NestedComp.ngComponentDef as ComponentDef<any>)];
// /NON-NORMATIVE // /NON-NORMATIVE
expect(renderComp(MyApp)) expect(renderComp(MyApp))

View File

@ -7,10 +7,13 @@
*/ */
import {browserDetection} from '@angular/platform-browser/testing/src/browser_util'; import {browserDetection} from '@angular/platform-browser/testing/src/browser_util';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core'; import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
import * as $r3$ from '../../../src/core_render3_private_export'; import * as $r3$ from '../../../src/core_render3_private_export';
import {ComponentDef} from '../../../src/render3/interfaces/definition';
import {ComponentFixture, renderComponent, toHtml} from '../render_util'; import {ComponentFixture, renderComponent, toHtml} from '../render_util';
/// See: `normative.md` /// See: `normative.md`
describe('elements', () => { describe('elements', () => {
// Saving type as $any$, etc to simplify testing for compiler, as types aren't saved // Saving type as $any$, etc to simplify testing for compiler, as types aren't saved
@ -103,7 +106,7 @@ describe('elements', () => {
} }
// NON-NORMATIVE // NON-NORMATIVE
LocalRefComp.ngComponentDef.directiveDefs = () => [Dir.ngDirectiveDef]; (LocalRefComp.ngComponentDef as ComponentDef<any>).directiveDefs = () => [Dir.ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE
const fixture = new ComponentFixture(LocalRefComp); const fixture = new ComponentFixture(LocalRefComp);

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 {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectableDef, Injector, InjectorDef, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, SkipSelf, TemplateRef, ViewChild, ViewChildren, ViewContainerRef, defineInjectable, defineInjector, inject} from '../../../src/core'; import {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, Injector, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, SkipSelf, TemplateRef, ViewChild, ViewChildren, ViewContainerRef, defineInjectable, defineInjector, inject} from '../../../src/core';
import * as $r3$ from '../../../src/core_render3_private_export'; import * as $r3$ from '../../../src/core_render3_private_export';
import {renderComponent, toHtml} from '../render_util'; import {renderComponent, toHtml} from '../render_util';

View File

@ -8,8 +8,10 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core'; import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
import * as $r3$ from '../../../src/core_render3_private_export'; import * as $r3$ from '../../../src/core_render3_private_export';
import {ComponentDef} from '../../../src/render3/interfaces/definition';
import {renderComponent, toHtml} from '../render_util'; import {renderComponent, toHtml} from '../render_util';
/// See: `normative.md` /// See: `normative.md`
describe('lifecycle hooks', () => { describe('lifecycle hooks', () => {
let events: string[] = []; let events: string[] = [];
@ -83,7 +85,7 @@ describe('lifecycle hooks', () => {
} }
// NON-NORMATIVE // NON-NORMATIVE
SimpleLayout.ngComponentDef.directiveDefs = [LifecycleComp.ngComponentDef]; (SimpleLayout.ngComponentDef as ComponentDef<any>).directiveDefs = [LifecycleComp.ngComponentDef];
// /NON-NORMATIVE // /NON-NORMATIVE
it('should gen hooks with a few simple components', () => { it('should gen hooks with a few simple components', () => {

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 {Component, ContentChild, Directive, Injectable, InjectableDef, InjectorDef, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, defineInjectable, defineInjector} from '../../../src/core'; import {Component, ContentChild, Directive, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, defineInjectable, defineInjector} from '../../../src/core';
import * as r3 from '../../../src/render3/index'; import * as r3 from '../../../src/render3/index';

View File

@ -8,8 +8,10 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core'; import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
import * as $r3$ from '../../../src/core_render3_private_export'; import * as $r3$ from '../../../src/core_render3_private_export';
import {ComponentDef} from '../../../src/render3/interfaces/definition';
import {containerEl, renderComponent, toHtml} from '../render_util'; import {containerEl, renderComponent, toHtml} from '../render_util';
/// See: `normative.md` /// See: `normative.md`
describe('pipes', () => { describe('pipes', () => {
type $any$ = any; type $any$ = any;
@ -96,7 +98,8 @@ describe('pipes', () => {
} }
// NON-NORMATIVE // NON-NORMATIVE
MyApp.ngComponentDef.pipeDefs = () => [MyPurePipe.ngPipeDef, MyPipe.ngPipeDef]; (MyApp.ngComponentDef as ComponentDef<any>).pipeDefs =
() => [MyPurePipe.ngPipeDef, MyPipe.ngPipeDef];
// /NON-NORMATIVE // /NON-NORMATIVE
let myApp: MyApp = renderComponent(MyApp); let myApp: MyApp = renderComponent(MyApp);
@ -189,8 +192,8 @@ describe('pipes', () => {
} }
// NON-NORMATIVE // NON-NORMATIVE
MyApp.ngComponentDef.directiveDefs = [OneTimeIf.ngDirectiveDef]; (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs = [OneTimeIf.ngDirectiveDef];
MyApp.ngComponentDef.pipeDefs = [MyPurePipe.ngPipeDef]; (MyApp.ngComponentDef as ComponentDef<any>).pipeDefs = [MyPurePipe.ngPipeDef];
// /NON-NORMATIVE // /NON-NORMATIVE
let myApp: MyApp = renderComponent(MyApp); let myApp: MyApp = renderComponent(MyApp);

View File

@ -8,8 +8,10 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core'; import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
import * as $r3$ from '../../../src/core_render3_private_export'; import * as $r3$ from '../../../src/core_render3_private_export';
import {ComponentDef} from '../../../src/render3/interfaces/definition';
import {renderComponent, toHtml} from '../render_util'; import {renderComponent, toHtml} from '../render_util';
/// See: `normative.md` /// See: `normative.md`
describe('queries', () => { describe('queries', () => {
type $RenderFlags$ = $r3$.ɵRenderFlags; type $RenderFlags$ = $r3$.ɵRenderFlags;
@ -70,7 +72,8 @@ describe('queries', () => {
} }
// NON-NORMATIVE // NON-NORMATIVE
ViewQueryComponent.ngComponentDef.directiveDefs = [SomeDirective.ngDirectiveDef]; (ViewQueryComponent.ngComponentDef as ComponentDef<any>).directiveDefs =
[SomeDirective.ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE
const viewQueryComp = renderComponent(ViewQueryComponent); const viewQueryComp = renderComponent(ViewQueryComponent);
@ -154,7 +157,7 @@ describe('queries', () => {
} }
// NON-NORMATIVE // NON-NORMATIVE
MyApp.ngComponentDef.directiveDefs = (MyApp.ngComponentDef as ComponentDef<any>).directiveDefs =
[ContentQueryComponent.ngComponentDef, SomeDirective.ngDirectiveDef]; [ContentQueryComponent.ngComponentDef, SomeDirective.ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE

View File

@ -7,7 +7,7 @@
*/ */
import {NgForOf, NgForOfContext} from '@angular/common'; import {NgForOf, NgForOfContext} from '@angular/common';
import {Component, ContentChild, Directive, EventEmitter, Injectable, InjectableDef, InjectorDef, Input, NgModule, OnDestroy, Optional, Output, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, defineInjectable, defineInjector} from '@angular/core'; import {Component, ContentChild, Directive, EventEmitter, Injectable, Input, NgModule, OnDestroy, Optional, Output, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, defineInjectable, defineInjector} from '@angular/core';
import {withBody} from '@angular/core/testing'; import {withBody} from '@angular/core/testing';
import * as r3 from '../../../src/render3/index'; import * as r3 from '../../../src/render3/index';
@ -96,7 +96,7 @@ class ToDoAppComponent {
} }
// NON-NORMATIVE // NON-NORMATIVE
ToDoAppComponent.ngComponentDef.directiveDefs = () => (ToDoAppComponent.ngComponentDef as r3.ComponentDef<any>).directiveDefs = () =>
[ToDoItemComponent.ngComponentDef, (NgForOf as r3.DirectiveType<NgForOf<any>>).ngDirectiveDef]; [ToDoItemComponent.ngComponentDef, (NgForOf as r3.DirectiveType<NgForOf<any>>).ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE

View File

@ -8,8 +8,10 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core'; import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
import * as $r3$ from '../../../src/core_render3_private_export'; import * as $r3$ from '../../../src/core_render3_private_export';
import {ComponentDef} from '../../../src/render3/interfaces/definition';
import {renderComponent, toHtml} from '../render_util'; import {renderComponent, toHtml} from '../render_util';
/// See: `normative.md` /// See: `normative.md`
describe('template variables', () => { describe('template variables', () => {
type $any$ = any; type $any$ = any;
@ -123,7 +125,8 @@ describe('template variables', () => {
} }
// NON-NORMATIVE // NON-NORMATIVE
MyComponent.ngComponentDef.directiveDefs = [ForOfDirective.ngDirectiveDef]; (MyComponent.ngComponentDef as ComponentDef<any>).directiveDefs =
[ForOfDirective.ngDirectiveDef];
// /NON-NORMATIVE // /NON-NORMATIVE
// TODO(chuckj): update when the changes to enable ngForOf lands. // TODO(chuckj): update when the changes to enable ngForOf lands.

View File

@ -11,7 +11,7 @@ import {ComponentFactory, DoCheck, ViewEncapsulation, createInjector, defineInje
import {getRenderedText} from '../../src/render3/component'; import {getRenderedText} from '../../src/render3/component';
import {LifecycleHooksFeature, defineComponent, directiveInject, markDirty} from '../../src/render3/index'; import {LifecycleHooksFeature, defineComponent, directiveInject, markDirty} from '../../src/render3/index';
import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, text, textBinding, tick} from '../../src/render3/instructions'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, text, textBinding, tick} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition'; import {ComponentDef, DirectiveDef, RenderFlags} from '../../src/render3/interfaces/definition';
import {createRendererType2} from '../../src/view/index'; import {createRendererType2} from '../../src/view/index';
import {getRendererFactory2} from './imported_renderer2'; import {getRendererFactory2} from './imported_renderer2';
@ -346,7 +346,8 @@ describe('recursive components', () => {
}); });
} }
TreeComponent.ngComponentDef.directiveDefs = () => [TreeComponent.ngComponentDef]; (TreeComponent.ngComponentDef as ComponentDef<TreeComponent>).directiveDefs =
() => [TreeComponent.ngComponentDef];
function _buildTree(currDepth: number): TreeNode { function _buildTree(currDepth: number): TreeNode {
const children = currDepth < 2 ? _buildTree(currDepth + 1) : null; const children = currDepth < 2 ? _buildTree(currDepth + 1) : null;

View File

@ -7,7 +7,7 @@
*/ */
import {DoCheck, OnChanges, SimpleChanges} from '../../src/core'; import {DoCheck, OnChanges, SimpleChanges} from '../../src/core';
import {NgOnChangesFeature, defineDirective} from '../../src/render3/index'; import {DirectiveDef, NgOnChangesFeature, defineDirective} from '../../src/render3/index';
describe('define', () => { describe('define', () => {
describe('component', () => { describe('component', () => {
@ -36,14 +36,15 @@ describe('define', () => {
}); });
} }
const myDir = MyDirective.ngDirectiveDef.factory() as MyDirective; const myDir =
(MyDirective.ngDirectiveDef as DirectiveDef<MyDirective>).factory() as MyDirective;
myDir.valA = 'first'; myDir.valA = 'first';
expect(myDir.valA).toEqual('first'); expect(myDir.valA).toEqual('first');
myDir.valB = 'second'; myDir.valB = 'second';
expect(myDir.log).toEqual(['second']); expect(myDir.log).toEqual(['second']);
expect(myDir.valB).toEqual('works'); expect(myDir.valB).toEqual('works');
myDir.log.length = 0; myDir.log.length = 0;
MyDirective.ngDirectiveDef.doCheck !.call(myDir); (MyDirective.ngDirectiveDef as DirectiveDef<MyDirective>).doCheck !.call(myDir);
expect(myDir.log).toEqual([ expect(myDir.log).toEqual([
'ngOnChanges', 'valA', 'initValue', 'first', 'valB', undefined, 'second', 'ngDoCheck' 'ngOnChanges', 'valA', 'initValue', 'first', 'valB', undefined, 'second', 'ngDoCheck'
]); ]);

View File

@ -244,14 +244,14 @@ export declare class DefaultIterableDiffer<V> implements IterableDiffer<V>, Iter
export declare function defineInjectable<T>(opts: { export declare function defineInjectable<T>(opts: {
providedIn?: Type<any> | 'root' | 'any' | null; providedIn?: Type<any> | 'root' | 'any' | null;
factory: () => T; factory: () => T;
}): InjectableDef<T>; }): never;
/** @experimental */ /** @experimental */
export declare function defineInjector(options: { export declare function defineInjector(options: {
factory: () => any; factory: () => any;
providers?: any[]; providers?: any[];
imports?: any[]; imports?: any[];
}): InjectorDef<any>; }): never;
/** @experimental */ /** @experimental */
export declare function destroyPlatform(): void; export declare function destroyPlatform(): void;
@ -354,19 +354,12 @@ export interface InjectableDecorator {
} & InjectableProvider): Injectable; } & InjectableProvider): Injectable;
} }
/** @experimental */
export interface InjectableDef<T> {
factory: () => T;
providedIn: InjectorType<any> | 'root' | 'any' | null;
value: T | undefined;
}
/** @experimental */ /** @experimental */
export declare type InjectableProvider = ValueSansProvider | ExistingSansProvider | StaticClassSansProvider | ConstructorSansProvider | FactorySansProvider | ClassSansProvider; export declare type InjectableProvider = ValueSansProvider | ExistingSansProvider | StaticClassSansProvider | ConstructorSansProvider | FactorySansProvider | ClassSansProvider;
/** @experimental */ /** @experimental */
export interface InjectableType<T> extends Type<T> { export interface InjectableType<T> extends Type<T> {
ngInjectableDef: InjectableDef<T>; ngInjectableDef: never;
} }
export interface InjectDecorator { export interface InjectDecorator {
@ -384,7 +377,7 @@ export declare const enum InjectFlags {
export declare class InjectionToken<T> { export declare class InjectionToken<T> {
protected _desc: string; protected _desc: string;
readonly ngInjectableDef: InjectableDef<T> | undefined; readonly ngInjectableDef: never | undefined;
constructor(_desc: string, options?: { constructor(_desc: string, options?: {
providedIn?: Type<any> | 'root' | null; providedIn?: Type<any> | 'root' | null;
factory: () => T; factory: () => T;
@ -397,7 +390,7 @@ export declare abstract class Injector {
/** @deprecated */ abstract get(token: any, notFoundValue?: any): any; /** @deprecated */ abstract get(token: any, notFoundValue?: any): any;
static NULL: Injector; static NULL: Injector;
static THROW_IF_NOT_FOUND: Object; static THROW_IF_NOT_FOUND: Object;
static ngInjectableDef: InjectableDef<Injector>; static ngInjectableDef: never;
/** @deprecated */ static create(providers: StaticProvider[], parent?: Injector): Injector; /** @deprecated */ static create(providers: StaticProvider[], parent?: Injector): Injector;
static create(options: { static create(options: {
providers: StaticProvider[]; providers: StaticProvider[];
@ -409,22 +402,9 @@ export declare abstract class Injector {
/** @experimental */ /** @experimental */
export declare const INJECTOR: InjectionToken<Injector>; export declare const INJECTOR: InjectionToken<Injector>;
/** @experimental */
export interface InjectorDef<T> {
factory: () => T;
imports: (InjectorType<any> | InjectorTypeWithProviders<any>)[];
providers: (Type<any> | ValueProvider | ExistingProvider | FactoryProvider | ConstructorProvider | StaticClassProvider | ClassProvider | any[])[];
}
/** @experimental */ /** @experimental */
export interface InjectorType<T> extends Type<T> { export interface InjectorType<T> extends Type<T> {
ngInjectorDef: InjectorDef<T>; ngInjectorDef: never;
}
/** @experimental */
export interface InjectorTypeWithProviders<T> {
ngModule: InjectorType<T>;
providers?: (Type<any> | ValueProvider | ExistingProvider | FactoryProvider | ConstructorProvider | StaticClassProvider | ClassProvider | any[])[];
} }
export declare const Input: InputDecorator; export declare const Input: InputDecorator;
@ -462,7 +442,7 @@ export declare class IterableDiffers {
/** @deprecated */ factories: IterableDifferFactory[]; /** @deprecated */ factories: IterableDifferFactory[];
constructor(factories: IterableDifferFactory[]); constructor(factories: IterableDifferFactory[]);
find(iterable: any): IterableDifferFactory; find(iterable: any): IterableDifferFactory;
static ngInjectableDef: InjectableDef<IterableDiffers>; static ngInjectableDef: never;
static create(factories: IterableDifferFactory[], parent?: IterableDiffers): IterableDiffers; static create(factories: IterableDifferFactory[], parent?: IterableDiffers): IterableDiffers;
static extend(factories: IterableDifferFactory[]): StaticProvider; static extend(factories: IterableDifferFactory[]): StaticProvider;
} }