refactor(ivy): make return value of define(Component|Directive|Pipe|Injector|Injectable) private (#23371)
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 `OpaqueToken`. By prefixing the type with `ɵ` we are communicating the the outside world that the value is not public API and is subject to change without backward compatibility. PR Close #23371
This commit is contained in:

committed by
Igor Minar

parent
f4017ce5e3
commit
2c09b707ce
@ -17,14 +17,15 @@ import {ClassProvider, ClassSansProvider, ConstructorProvider, ConstructorSansPr
|
||||
* requesting injection of other types if necessary.
|
||||
*
|
||||
* Optionally, a `providedIn` parameter specifies that the given type belongs to a particular
|
||||
* `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.
|
||||
*
|
||||
* This type is typically generated by the Angular compiler, but can be hand-written if needed.
|
||||
* NOTE: This is a semi public API, and there are no guaranties that the shape of this API will
|
||||
* remain consistent between version. Use with caution.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export interface InjectableDef<T> {
|
||||
export interface ɵInjectableDef<T> {
|
||||
/**
|
||||
* Specifies that the given type belongs to a particular injector:
|
||||
* - `InjectorType` such as `NgModule`,
|
||||
@ -50,13 +51,13 @@ export interface InjectableDef<T> {
|
||||
* Information about the providers to be included in an `Injector` as well as how the given type
|
||||
* which carries the information should be created by the DI system.
|
||||
*
|
||||
* An `InjectorDef` can import other types which have `InjectorDefs`, forming a deep nested
|
||||
* An `ɵInjectorDef` can import other types which have `InjectorDefs`, forming a deep nested
|
||||
* structure of providers with a defined priority (identically to how `NgModule`s also have
|
||||
* an import/dependency structure).
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export interface InjectorDef<T> {
|
||||
export interface ɵInjectorDef<T> {
|
||||
factory: () => T;
|
||||
|
||||
// TODO(alxhub): Narrow down the type here once decorators properly change the return type of the
|
||||
@ -68,29 +69,29 @@ export interface InjectorDef<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Type` which has an `InjectableDef` static field.
|
||||
* A `Type` which has an `ɵInjectableDef` static field.
|
||||
*
|
||||
* `InjectableDefType`s contain their own Dependency Injection metadata and are usable in an
|
||||
* `InjectorDef`-based `StaticInjector.
|
||||
* `ɵInjectorDef`-based `StaticInjector.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export interface InjectableType<T> extends Type<T> { ngInjectableDef: InjectableDef<T>; }
|
||||
export interface InjectableType<T> extends Type<T> { ngInjectableDef: ɵInjectableDef<T>; }
|
||||
|
||||
/**
|
||||
* A type which has an `InjectorDef` static field.
|
||||
* A type which has an `ɵInjectorDef` static field.
|
||||
*
|
||||
* `InjectorDefTypes` can be used to configure a `StaticInjector`.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export interface InjectorType<T> extends Type<T> { ngInjectorDef: InjectorDef<T>; }
|
||||
export interface InjectorType<T> extends Type<T> { ngInjectorDef: ɵInjectorDef<T>; }
|
||||
|
||||
/**
|
||||
* Describes the `InjectorDef` equivalent of a `ModuleWithProviders`, an `InjectorDefType` with an
|
||||
* Describes the `ɵInjectorDef` equivalent of a `ModuleWithProviders`, an `InjectorDefType` with an
|
||||
* associated array of providers.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
@ -102,7 +103,7 @@ export interface InjectorTypeWithProviders<T> {
|
||||
|
||||
|
||||
/**
|
||||
* Construct an `InjectableDef` which defines how a token will be constructed by the DI system, and
|
||||
* Construct an `ɵInjectableDef` which defines how a token will be constructed by the DI system, and
|
||||
* in which injectors (if any) it will be available.
|
||||
*
|
||||
* This should be assigned to a static `ngInjectableDef` field on a type, which will then be an
|
||||
@ -120,7 +121,7 @@ export interface InjectorTypeWithProviders<T> {
|
||||
export function defineInjectable<T>(opts: {
|
||||
providedIn?: Type<any>| 'root' | 'any' | null,
|
||||
factory: () => T,
|
||||
}): InjectableDef<T> {
|
||||
}): ɵInjectableDef<T> {
|
||||
return {
|
||||
providedIn: opts.providedIn as any || null,
|
||||
factory: opts.factory,
|
||||
@ -129,7 +130,7 @@ export function defineInjectable<T>(opts: {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an `InjectorDef` which configures an injector.
|
||||
* Construct an `ɵInjectorDef` which configures an injector.
|
||||
*
|
||||
* This should be assigned to a static `ngInjectorDef` field on a type, which will then be an
|
||||
* `InjectorType`.
|
||||
@ -149,7 +150,7 @@ export function defineInjectable<T>(opts: {
|
||||
* @experimental
|
||||
*/
|
||||
export function defineInjector(options: {factory: () => any, providers?: any[], imports?: any[]}):
|
||||
InjectorDef<any> {
|
||||
ɵInjectorDef<any> {
|
||||
return {
|
||||
factory: options.factory,
|
||||
providers: options.providers || [],
|
||||
|
@ -11,7 +11,7 @@ import {Type} from '../type';
|
||||
import {makeDecorator, makeParamDecorator} from '../util/decorators';
|
||||
import {getClosureSafeProperty} from '../util/property';
|
||||
|
||||
import {InjectableDef, InjectableType, defineInjectable} from './defs';
|
||||
import {InjectableType, defineInjectable, ɵInjectableDef} from './defs';
|
||||
import {inject, injectArgs} from './injector';
|
||||
import {ClassSansProvider, ConstructorProvider, ConstructorSansProvider, ExistingProvider, ExistingSansProvider, FactoryProvider, FactorySansProvider, StaticClassProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from './provider';
|
||||
|
||||
@ -134,4 +134,4 @@ export const Injectable: InjectableDecorator = makeDecorator(
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export interface InjectableType<T> extends Type<T> { ngInjectableDef: InjectableDef<T>; }
|
||||
export interface InjectableType<T> extends Type<T> { ngInjectableDef: ɵInjectableDef<T>; }
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
import {Type} from '../type';
|
||||
|
||||
import {InjectableDef, defineInjectable} from './defs';
|
||||
import {defineInjectable, ɵInjectableDef} from './defs';
|
||||
|
||||
|
||||
/**
|
||||
* Creates a token that can be used in a DI Provider.
|
||||
@ -52,7 +53,7 @@ export class InjectionToken<T> {
|
||||
/** @internal */
|
||||
readonly ngMetadataName = 'InjectionToken';
|
||||
|
||||
readonly ngInjectableDef: InjectableDef<T>|undefined;
|
||||
readonly ngInjectableDef: ɵInjectableDef<T>|undefined;
|
||||
|
||||
constructor(protected _desc: string, options?: {
|
||||
providedIn?: Type<any>| 'root' | null,
|
||||
@ -72,5 +73,5 @@ export class InjectionToken<T> {
|
||||
}
|
||||
|
||||
export interface InjectableDefToken<T> extends InjectionToken<T> {
|
||||
ngInjectableDef: InjectableDef<T>;
|
||||
ngInjectableDef: ɵInjectableDef<T>;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
import {Type} from '../type';
|
||||
import {stringify} from '../util';
|
||||
|
||||
import {InjectableDef, defineInjectable} from './defs';
|
||||
import {defineInjectable, ɵInjectableDef} from './defs';
|
||||
import {resolveForwardRef} from './forward_ref';
|
||||
import {InjectionToken} from './injection_token';
|
||||
import {Inject, Optional, Self, SkipSelf} from './metadata';
|
||||
@ -462,7 +462,7 @@ export function inject<T>(token: Type<T>| InjectionToken<T>, flags = InjectFlags
|
||||
if (_currentInjector === undefined) {
|
||||
throw new Error(`inject() must be called from an injection context`);
|
||||
} else if (_currentInjector === null) {
|
||||
const injectableDef: InjectableDef<T> = (token as any).ngInjectableDef;
|
||||
const injectableDef: ɵInjectableDef<T> = (token as any).ngInjectableDef;
|
||||
if (injectableDef && injectableDef.providedIn == 'root') {
|
||||
return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
|
||||
injectableDef.value;
|
||||
|
@ -10,7 +10,7 @@ import {OnDestroy} from '../metadata/lifecycle_hooks';
|
||||
import {Type} from '../type';
|
||||
import {stringify} from '../util';
|
||||
|
||||
import {InjectableDef, InjectableType, InjectorDef, InjectorType, InjectorTypeWithProviders} from './defs';
|
||||
import {InjectableType, InjectorType, InjectorTypeWithProviders, ɵInjectableDef, ɵInjectorDef} from './defs';
|
||||
import {resolveForwardRef} from './forward_ref';
|
||||
import {InjectableDefToken, InjectionToken} from './injection_token';
|
||||
import {INJECTOR, InjectFlags, Injector, NullInjector, THROW_IF_NOT_FOUND, USE_VALUE, inject, injectArgs, setCurrentInjector} from './injector';
|
||||
@ -200,7 +200,7 @@ export class R3Injector {
|
||||
// read, so care is taken to only do the read once.
|
||||
|
||||
// First attempt to read the ngInjectorDef.
|
||||
let def = (defOrWrappedDef as InjectorType<any>).ngInjectorDef as(InjectorDef<any>| undefined);
|
||||
let def = (defOrWrappedDef as InjectorType<any>).ngInjectorDef as(ɵInjectorDef<any>| undefined);
|
||||
|
||||
// If that's not present, then attempt to read ngModule from the InjectorDefTypeWithProviders.
|
||||
const ngModule =
|
||||
@ -219,7 +219,7 @@ export class R3Injector {
|
||||
EMPTY_ARRAY;
|
||||
|
||||
// Finally, if defOrWrappedType was an `InjectorDefTypeWithProviders`, then the actual
|
||||
// `InjectorDef` is on its `ngModule`.
|
||||
// `ɵInjectorDef` is on its `ngModule`.
|
||||
if (ngModule !== undefined) {
|
||||
def = ngModule.ngInjectorDef;
|
||||
}
|
||||
@ -314,7 +314,7 @@ export class R3Injector {
|
||||
return record.value as T;
|
||||
}
|
||||
|
||||
private injectableDefInScope(def: InjectableDef<any>): boolean {
|
||||
private injectableDefInScope(def: ɵInjectableDef<any>): boolean {
|
||||
if (!def.providedIn) {
|
||||
return false;
|
||||
} else if (typeof def.providedIn === 'string') {
|
||||
|
Reference in New Issue
Block a user