fix(ivy): fix type error in newer version of TS (#22897)

Newer version of TS is stricter about types and flags counter-variant
types in some  situations. This change inlines the DirectiveDefArgs
into the arguments which:
1) removes the inheritance which caused the issue and
2) Makes it more friendly to IDEs since they will not report comments.

Closes #22877
Closes #22843

PR Close #22897
This commit is contained in:
Miško Hevery 2018-03-20 14:44:22 -07:00 committed by Igor Minar
parent 3cc5c2e4d0
commit 17fb9832f4
3 changed files with 180 additions and 138 deletions

View File

@ -9,13 +9,14 @@
import {SimpleChange} from '../change_detection/change_detection_util'; import {SimpleChange} from '../change_detection/change_detection_util';
import {ChangeDetectionStrategy} from '../change_detection/constants'; import {ChangeDetectionStrategy} from '../change_detection/constants';
import {PipeTransform} from '../change_detection/pipe_transform'; import {PipeTransform} from '../change_detection/pipe_transform';
import {Provider} from '../core';
import {OnChanges, SimpleChanges} from '../metadata/lifecycle_hooks'; import {OnChanges, SimpleChanges} from '../metadata/lifecycle_hooks';
import {RendererType2} from '../render/api'; import {RendererType2} from '../render/api';
import {Type} from '../type'; import {Type} from '../type';
import {resolveRendererType2} from '../view/util'; import {resolveRendererType2} from '../view/util';
import {diPublic} from './di'; import {diPublic} from './di';
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, DirectiveDefFeature, PipeDef} from './interfaces/definition'; import {ComponentDef, ComponentDefFeature, ComponentTemplate, DirectiveDef, DirectiveDefFeature, PipeDef} from './interfaces/definition';
@ -34,14 +35,126 @@ import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, Directiv
* } * }
* ``` * ```
*/ */
export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): ComponentDef<T> { export function defineComponent<T>(componentDefinition: {
/**
* Directive type, needed to configure the injector.
*/
type: Type<T>;
/**
* Factory method used to create an instance of directive.
*/
factory: () => T | ({0: T} & any[]); /* trying to say T | [T, ...any] */
/**
* Static attributes to set on host element.
*
* Even indices: attribute name
* Odd indices: attribute value
*/
attributes?: string[];
/**
* A map of input names.
*
* The format is in: `{[actualPropertyName: string]:string}`.
*
* Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.
*
* This allows the render to re-construct the minified and non-minified names
* of properties.
*/
inputs?: {[P in keyof T]?: string};
/**
* A map of output names.
*
* The format is in: `{[actualPropertyName: string]:string}`.
*
* Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.
*
* This allows the render to re-construct the minified and non-minified names
* of properties.
*/
outputs?: {[P in keyof T]?: string};
/**
* Function executed by the parent template to allow child directive to apply host bindings.
*/
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
/**
* Defines the name that can be used in the template to assign this directive to a variable.
*
* See: {@link Directive.exportAs}
*/
exportAs?: string;
/**
* HTML tag name to use in place where this component should be instantiated.
*/
tag: string;
/**
* Template function use for rendering DOM.
*
* This function has following structure.
*
* ```
* function Template<T>(ctx:T, creationMode: boolean) {
* if (creationMode) {
* // Contains creation mode instructions.
* }
* // Contains binding update instructions
* }
* ```
*
* Common instructions are:
* Creation mode instructions:
* - `elementStart`, `elementEnd`
* - `text`
* - `container`
* - `listener`
*
* Binding update instructions:
* - `bind`
* - `elementAttribute`
* - `elementProperty`
* - `elementClass`
* - `elementStyle`
*
*/
template: ComponentTemplate<T>;
/**
* A list of optional features to apply.
*
* See: {@link NgOnChangesFeature}, {@link PublicFeature}
*/
features?: ComponentDefFeature[];
rendererType?: RendererType2;
changeDetection?: ChangeDetectionStrategy;
/**
* Defines the set of injectable objects that are visible to a Directive and its light DOM
* children.
*/
providers?: Provider[];
/**
* Defines the set of injectable objects that are visible to its view DOM children.
*/
viewProviders?: Provider[];
}): ComponentDef<T> {
const type = componentDefinition.type; const type = componentDefinition.type;
const def = <ComponentDef<any>>{ const def = <ComponentDef<any>>{
type: type, type: type,
diPublic: null, diPublic: null,
factory: componentDefinition.factory, factory: componentDefinition.factory,
tag: (componentDefinition as ComponentDefArgs<T>).tag || null !, tag: componentDefinition.tag || null !,
template: (componentDefinition as ComponentDefArgs<T>).template || null !, template: componentDefinition.template || null !,
hostBindings: componentDefinition.hostBindings || null, hostBindings: componentDefinition.hostBindings || null,
attributes: componentDefinition.attributes || null, attributes: componentDefinition.attributes || null,
inputs: invertObject(componentDefinition.inputs), inputs: invertObject(componentDefinition.inputs),
@ -55,8 +168,7 @@ export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): Co
afterViewInit: type.prototype.ngAfterViewInit || null, afterViewInit: type.prototype.ngAfterViewInit || null,
afterViewChecked: type.prototype.ngAfterViewChecked || null, afterViewChecked: type.prototype.ngAfterViewChecked || null,
onDestroy: type.prototype.ngOnDestroy || null, onDestroy: type.prototype.ngOnDestroy || null,
onPush: (componentDefinition as ComponentDefArgs<T>).changeDetection === onPush: componentDefinition.changeDetection === ChangeDetectionStrategy.OnPush
ChangeDetectionStrategy.OnPush
}; };
const feature = componentDefinition.features; const feature = componentDefinition.features;
feature && feature.forEach((fn) => fn(def)); feature && feature.forEach((fn) => fn(def));
@ -182,8 +294,68 @@ function invertObject(obj: any): any {
* } * }
* ``` * ```
*/ */
export const defineDirective = defineComponent as<T>(directiveDefinition: DirectiveDefArgs<T>) => export const defineDirective = defineComponent as any as<T>(directiveDefinition: {
DirectiveDef<T>; /**
* Directive type, needed to configure the injector.
*/
type: Type<T>;
/**
* Factory method used to create an instance of directive.
*/
factory: () => T | ({0: T} & any[]); /* trying to say T | [T, ...any] */
/**
* Static attributes to set on host element.
*
* Even indices: attribute name
* Odd indices: attribute value
*/
attributes?: string[];
/**
* A map of input names.
*
* The format is in: `{[actualPropertyName: string]:string}`.
*
* Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.
*
* This allows the render to re-construct the minified and non-minified names
* of properties.
*/
inputs?: {[P in keyof T]?: string};
/**
* A map of output names.
*
* The format is in: `{[actualPropertyName: string]:string}`.
*
* Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.
*
* This allows the render to re-construct the minified and non-minified names
* of properties.
*/
outputs?: {[P in keyof T]?: string};
/**
* A list of optional features to apply.
*
* See: {@link NgOnChangesFeature}, {@link PublicFeature}
*/
features?: DirectiveDefFeature[];
/**
* Function executed by the parent template to allow child directive to apply host bindings.
*/
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
/**
* Defines the name that can be used in the template to assign this directive to a variable.
*
* See: {@link Directive.exportAs}
*/
exportAs?: string;
}) => DirectiveDef<T>;
/** /**
* Create a pipe definition object. * Create a pipe definition object.

View File

@ -192,135 +192,6 @@ export interface PipeDef<T> {
onDestroy: (() => void)|null; onDestroy: (() => void)|null;
} }
/**
* Arguments for `defineDirective`
*/
export interface DirectiveDefArgs<T> {
/**
* Directive type, needed to configure the injector.
*/
type: Type<T>;
/**
* Factory method used to create an instance of directive.
*/
factory: () => T | ({0: T} & any[]); /* trying to say T | [T, ...any] */
/**
* Static attributes to set on host element.
*
* Even indices: attribute name
* Odd indices: attribute value
*/
attributes?: string[];
/**
* A map of input names.
*
* The format is in: `{[actualPropertyName: string]:string}`.
*
* Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.
*
* This allows the render to re-construct the minified and non-minified names
* of properties.
*/
inputs?: {[P in keyof T]?: string};
/**
* A map of output names.
*
* The format is in: `{[actualPropertyName: string]:string}`.
*
* Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.
*
* This allows the render to re-construct the minified and non-minified names
* of properties.
*/
outputs?: {[P in keyof T]?: string};
/**
* A list of optional features to apply.
*
* See: {@link NgOnChangesFeature}, {@link PublicFeature}
*/
features?: DirectiveDefFeature[];
/**
* Function executed by the parent template to allow child directive to apply host bindings.
*/
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
/**
* Defines the name that can be used in the template to assign this directive to a variable.
*
* See: {@link Directive.exportAs}
*/
exportAs?: string;
}
/**
* Arguments for `defineComponent`.
*/
export interface ComponentDefArgs<T> extends DirectiveDefArgs<T> {
/**
* HTML tag name to use in place where this component should be instantiated.
*/
tag: string;
/**
* Template function use for rendering DOM.
*
* This function has following structure.
*
* ```
* function Template<T>(ctx:T, creationMode: boolean) {
* if (creationMode) {
* // Contains creation mode instructions.
* }
* // Contains binding update instructions
* }
* ```
*
* Common instructions are:
* Creation mode instructions:
* - `elementStart`, `elementEnd`
* - `text`
* - `container`
* - `listener`
*
* Binding update instructions:
* - `bind`
* - `elementAttribute`
* - `elementProperty`
* - `elementClass`
* - `elementStyle`
*
*/
template: ComponentTemplate<T>;
/**
* A list of optional features to apply.
*
* See: {@link NgOnChancesFeature}, {@link PublicFeature}
*/
features?: ComponentDefFeature[];
rendererType?: RendererType2;
changeDetection?: ChangeDetectionStrategy;
/**
* Defines the set of injectable objects that are visible to a Directive and its light DOM
* children.
*/
providers?: Provider[];
/**
* Defines the set of injectable objects that are visible to its view DOM children.
*/
viewProviders?: Provider[];
}
export type DirectiveDefFeature = <T>(directiveDef: DirectiveDef<T>) => void; export type DirectiveDefFeature = <T>(directiveDef: DirectiveDef<T>) => void;
export type ComponentDefFeature = <T>(componentDef: ComponentDef<T>) => void; export type ComponentDefFeature = <T>(componentDef: ComponentDef<T>) => void;

View File

@ -11,7 +11,6 @@ import {stringifyElement} from '@angular/platform-browser/testing/src/browser_ut
import {CreateComponentOptions} from '../../src/render3/component'; import {CreateComponentOptions} from '../../src/render3/component';
import {ComponentTemplate, ComponentType, DirectiveType, PublicFeature, defineComponent, defineDirective, renderComponent as _renderComponent, tick} from '../../src/render3/index'; import {ComponentTemplate, ComponentType, DirectiveType, PublicFeature, defineComponent, defineDirective, renderComponent as _renderComponent, tick} from '../../src/render3/index';
import {NG_HOST_SYMBOL, createLNode, createLView, renderTemplate} from '../../src/render3/instructions'; import {NG_HOST_SYMBOL, createLNode, createLView, renderTemplate} from '../../src/render3/instructions';
import {DirectiveDefArgs} from '../../src/render3/interfaces/definition';
import {LElementNode, LNodeFlags} from '../../src/render3/interfaces/node'; import {LElementNode, LNodeFlags} from '../../src/render3/interfaces/node';
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/interfaces/renderer'; import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/interfaces/renderer';