fix: argument destructuring sometimes breaks strictNullChecks

Destructuring of the form:

function foo({a, b}: {a?, b?} = {})

breaks strictNullChecks, due to the TypeScript bug https://github.com/microsoft/typescript/issues/10078.
This change eliminates usage of destructuring in function argument lists in cases where it would leak
into the public API .d.ts.
This commit is contained in:
Alex Rickabaugh 2017-06-12 10:59:29 -07:00 committed by Hans
parent 009651e14f
commit c59c390cdc
8 changed files with 91 additions and 97 deletions

View File

@ -13,16 +13,15 @@ export enum NumberFormatStyle {
}
export class NumberFormatter {
static format(
num: number, locale: string, style: NumberFormatStyle,
{minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, currency,
currencyAsSymbol = false}: {
minimumIntegerDigits?: number,
minimumFractionDigits?: number,
maximumFractionDigits?: number,
currency?: string|null,
currencyAsSymbol?: boolean
} = {}): string {
static format(num: number, locale: string, style: NumberFormatStyle, opts: {
minimumIntegerDigits?: number,
minimumFractionDigits?: number,
maximumFractionDigits?: number,
currency?: string|null,
currencyAsSymbol?: boolean
} = {}): string {
const {minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, currency,
currencyAsSymbol = false} = opts;
const options: Intl.NumberFormatOptions = {
minimumIntegerDigits,
minimumFractionDigits,

View File

@ -183,11 +183,8 @@ export interface ContentChildrenDecorator {
* @stable
* @Annotation
*/
(selector: Type<any>|Function|string,
{descendants, read}?: {descendants?: boolean, read?: any}): any;
new (
selector: Type<any>|Function|string,
{descendants, read}?: {descendants?: boolean, read?: any}): Query;
(selector: Type<any>|Function|string, opts?: {descendants?: boolean, read?: any}): any;
new (selector: Type<any>|Function|string, opts?: {descendants?: boolean, read?: any}): Query;
}
/**
@ -247,8 +244,8 @@ export interface ContentChildDecorator {
* @stable
* @Annotation
*/
(selector: Type<any>|Function|string, {read}?: {read?: any}): any;
new (selector: Type<any>|Function|string, {read}?: {read?: any}): ContentChild;
(selector: Type<any>|Function|string, opts?: {read?: any}): any;
new (selector: Type<any>|Function|string, opts?: {read?: any}): ContentChild;
}
/**
@ -308,8 +305,8 @@ export interface ViewChildrenDecorator {
* @stable
* @Annotation
*/
(selector: Type<any>|Function|string, {read}?: {read?: any}): any;
new (selector: Type<any>|Function|string, {read}?: {read?: any}): ViewChildren;
(selector: Type<any>|Function|string, opts?: {read?: any}): any;
new (selector: Type<any>|Function|string, opts?: {read?: any}): ViewChildren;
}
/**
@ -365,8 +362,8 @@ export interface ViewChildDecorator {
* @stable
* @Annotation
*/
(selector: Type<any>|Function|string, {read}?: {read?: any}): any;
new (selector: Type<any>|Function|string, {read}?: {read?: any}): ViewChild;
(selector: Type<any>|Function|string, opts?: {read?: any}): any;
new (selector: Type<any>|Function|string, opts?: {read?: any}): ViewChild;
}
/**

View File

@ -76,22 +76,21 @@ export class ViewMetadata {
/** {@link Component#interpolation} */
interpolation: [string, string]|undefined;
constructor(
{templateUrl, template, encapsulation, styles, styleUrls, animations, interpolation}: {
templateUrl?: string,
template?: string,
encapsulation?: ViewEncapsulation,
styles?: string[],
styleUrls?: string[],
animations?: any[],
interpolation?: [string, string]
} = {}) {
this.templateUrl = templateUrl;
this.template = template;
this.styleUrls = styleUrls;
this.styles = styles;
this.encapsulation = encapsulation;
this.animations = animations;
this.interpolation = interpolation;
constructor(opts: {
templateUrl?: string,
template?: string,
encapsulation?: ViewEncapsulation,
styles?: string[],
styleUrls?: string[],
animations?: any[],
interpolation?: [string, string]
} = {}) {
this.templateUrl = opts.templateUrl;
this.template = opts.template;
this.styleUrls = opts.styleUrls;
this.styles = opts.styles;
this.encapsulation = opts.encapsulation;
this.animations = opts.animations;
this.interpolation = opts.interpolation;
}
}

View File

@ -238,11 +238,11 @@ export abstract class AbstractControl {
* This will also mark all direct ancestors as `touched` to maintain
* the model.
*/
markAsTouched({onlySelf}: {onlySelf?: boolean} = {}): void {
markAsTouched(opts: {onlySelf?: boolean} = {}): void {
this._touched = true;
if (this._parent && !onlySelf) {
this._parent.markAsTouched({onlySelf});
if (this._parent && !opts.onlySelf) {
this._parent.markAsTouched(opts);
}
}
@ -253,14 +253,14 @@ export abstract class AbstractControl {
* to maintain the model, and re-calculate the `touched` status of all parent
* controls.
*/
markAsUntouched({onlySelf}: {onlySelf?: boolean} = {}): void {
markAsUntouched(opts: {onlySelf?: boolean} = {}): void {
this._touched = false;
this._forEachChild(
(control: AbstractControl) => { control.markAsUntouched({onlySelf: true}); });
if (this._parent && !onlySelf) {
this._parent._updateTouched({onlySelf});
if (this._parent && !opts.onlySelf) {
this._parent._updateTouched(opts);
}
}
@ -270,11 +270,11 @@ export abstract class AbstractControl {
* This will also mark all direct ancestors as `dirty` to maintain
* the model.
*/
markAsDirty({onlySelf}: {onlySelf?: boolean} = {}): void {
markAsDirty(opts: {onlySelf?: boolean} = {}): void {
this._pristine = false;
if (this._parent && !onlySelf) {
this._parent.markAsDirty({onlySelf});
if (this._parent && !opts.onlySelf) {
this._parent.markAsDirty(opts);
}
}
@ -285,24 +285,24 @@ export abstract class AbstractControl {
* to maintain the model, and re-calculate the `pristine` status of all parent
* controls.
*/
markAsPristine({onlySelf}: {onlySelf?: boolean} = {}): void {
markAsPristine(opts: {onlySelf?: boolean} = {}): void {
this._pristine = true;
this._forEachChild((control: AbstractControl) => { control.markAsPristine({onlySelf: true}); });
if (this._parent && !onlySelf) {
this._parent._updatePristine({onlySelf});
if (this._parent && !opts.onlySelf) {
this._parent._updatePristine(opts);
}
}
/**
* Marks the control as `pending`.
*/
markAsPending({onlySelf}: {onlySelf?: boolean} = {}): void {
markAsPending(opts: {onlySelf?: boolean} = {}): void {
this._status = PENDING;
if (this._parent && !onlySelf) {
this._parent.markAsPending({onlySelf});
if (this._parent && !opts.onlySelf) {
this._parent.markAsPending(opts);
}
}
@ -312,18 +312,18 @@ export abstract class AbstractControl {
*
* If the control has children, all children will be disabled to maintain the model.
*/
disable({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
disable(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
this._status = DISABLED;
this._errors = null;
this._forEachChild((control: AbstractControl) => { control.disable({onlySelf: true}); });
this._updateValue();
if (emitEvent !== false) {
if (opts.emitEvent !== false) {
this._valueChanges.emit(this._value);
this._statusChanges.emit(this._status);
}
this._updateAncestors(!!onlySelf);
this._updateAncestors(!!opts.onlySelf);
this._onDisabledChange.forEach((changeFn) => changeFn(true));
}
@ -334,12 +334,12 @@ export abstract class AbstractControl {
*
* If the control has children, all children will be enabled.
*/
enable({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
enable(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
this._status = VALID;
this._forEachChild((control: AbstractControl) => { control.enable({onlySelf: true}); });
this.updateValueAndValidity({onlySelf: true, emitEvent});
this.updateValueAndValidity({onlySelf: true, emitEvent: opts.emitEvent});
this._updateAncestors(!!onlySelf);
this._updateAncestors(!!opts.onlySelf);
this._onDisabledChange.forEach((changeFn) => changeFn(false));
}
@ -373,8 +373,7 @@ export abstract class AbstractControl {
*
* By default, it will also update the value and validity of its ancestors.
*/
updateValueAndValidity({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
void {
updateValueAndValidity(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
this._setInitialStatus();
this._updateValue();
@ -384,24 +383,24 @@ export abstract class AbstractControl {
this._status = this._calculateStatus();
if (this._status === VALID || this._status === PENDING) {
this._runAsyncValidator(emitEvent);
this._runAsyncValidator(opts.emitEvent);
}
}
if (emitEvent !== false) {
if (opts.emitEvent !== false) {
this._valueChanges.emit(this._value);
this._statusChanges.emit(this._status);
}
if (this._parent && !onlySelf) {
this._parent.updateValueAndValidity({onlySelf, emitEvent});
if (this._parent && !opts.onlySelf) {
this._parent.updateValueAndValidity(opts);
}
}
/** @internal */
_updateTreeValidity({emitEvent}: {emitEvent?: boolean} = {emitEvent: true}) {
this._forEachChild((ctrl: AbstractControl) => ctrl._updateTreeValidity({emitEvent}));
this.updateValueAndValidity({onlySelf: true, emitEvent});
_updateTreeValidity(opts: {emitEvent?: boolean} = {emitEvent: true}) {
this._forEachChild((ctrl: AbstractControl) => ctrl._updateTreeValidity(opts));
this.updateValueAndValidity({onlySelf: true, emitEvent: opts.emitEvent});
}
private _setInitialStatus() { this._status = this._allControlsDisabled() ? DISABLED : VALID; }
@ -448,9 +447,9 @@ export abstract class AbstractControl {
* expect(login.valid).toEqual(true);
* ```
*/
setErrors(errors: ValidationErrors|null, {emitEvent}: {emitEvent?: boolean} = {}): void {
setErrors(errors: ValidationErrors|null, opts: {emitEvent?: boolean} = {}): void {
this._errors = errors;
this._updateControlsErrors(emitEvent !== false);
this._updateControlsErrors(opts.emitEvent !== false);
}
/**
@ -556,20 +555,20 @@ export abstract class AbstractControl {
}
/** @internal */
_updatePristine({onlySelf}: {onlySelf?: boolean} = {}): void {
_updatePristine(opts: {onlySelf?: boolean} = {}): void {
this._pristine = !this._anyControlsDirty();
if (this._parent && !onlySelf) {
this._parent._updatePristine({onlySelf});
if (this._parent && !opts.onlySelf) {
this._parent._updatePristine(opts);
}
}
/** @internal */
_updateTouched({onlySelf}: {onlySelf?: boolean} = {}): void {
_updateTouched(opts: {onlySelf?: boolean} = {}): void {
this._touched = this._anyControlsTouched();
if (this._parent && !onlySelf) {
this._parent._updateTouched({onlySelf});
if (this._parent && !opts.onlySelf) {
this._parent._updateTouched(opts);
}
}

View File

@ -385,9 +385,9 @@ export class Router {
* router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
* ```
*/
createUrlTree(
commands: any[], {relativeTo, queryParams, fragment, preserveQueryParams, queryParamsHandling,
preserveFragment}: NavigationExtras = {}): UrlTree {
createUrlTree(commands: any[], navigationExtras: NavigationExtras = {}): UrlTree {
const {relativeTo, queryParams, fragment,
preserveQueryParams, queryParamsHandling, preserveFragment} = navigationExtras;
if (isDevMode() && preserveQueryParams && <any>console && <any>console.warn) {
console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
}

View File

@ -262,10 +262,10 @@ export declare const ContentChild: ContentChildDecorator;
/** @stable */
export interface ContentChildDecorator {
/** @stable */ (selector: Type<any> | Function | string, {read}?: {
/** @stable */ (selector: Type<any> | Function | string, opts?: {
read?: any;
}): any;
new (selector: Type<any> | Function | string, {read}?: {
new (selector: Type<any> | Function | string, opts?: {
read?: any;
}): ContentChild;
}
@ -275,11 +275,11 @@ export declare const ContentChildren: ContentChildrenDecorator;
/** @stable */
export interface ContentChildrenDecorator {
/** @stable */ (selector: Type<any> | Function | string, {descendants, read}?: {
/** @stable */ (selector: Type<any> | Function | string, opts?: {
descendants?: boolean;
read?: any;
}): any;
new (selector: Type<any> | Function | string, {descendants, read}?: {
new (selector: Type<any> | Function | string, opts?: {
descendants?: boolean;
read?: any;
}): Query;
@ -1058,10 +1058,10 @@ export declare const ViewChild: ViewChildDecorator;
/** @stable */
export interface ViewChildDecorator {
/** @stable */ (selector: Type<any> | Function | string, {read}?: {
/** @stable */ (selector: Type<any> | Function | string, opts?: {
read?: any;
}): any;
new (selector: Type<any> | Function | string, {read}?: {
new (selector: Type<any> | Function | string, opts?: {
read?: any;
}): ViewChild;
}
@ -1071,10 +1071,10 @@ export declare const ViewChildren: ViewChildrenDecorator;
/** @stable */
export interface ViewChildrenDecorator {
/** @stable */ (selector: Type<any> | Function | string, {read}?: {
/** @stable */ (selector: Type<any> | Function | string, opts?: {
read?: any;
}): any;
new (selector: Type<any> | Function | string, {read}?: {
new (selector: Type<any> | Function | string, opts?: {
read?: any;
}): ViewChildren;
}

View File

@ -21,42 +21,42 @@ export declare abstract class AbstractControl {
constructor(validator: ValidatorFn | null, asyncValidator: AsyncValidatorFn | null);
clearAsyncValidators(): void;
clearValidators(): void;
disable({onlySelf, emitEvent}?: {
disable(opts?: {
onlySelf?: boolean;
emitEvent?: boolean;
}): void;
enable({onlySelf, emitEvent}?: {
enable(opts?: {
onlySelf?: boolean;
emitEvent?: boolean;
}): void;
get(path: Array<string | number> | string): AbstractControl | null;
getError(errorCode: string, path?: string[]): any;
hasError(errorCode: string, path?: string[]): boolean;
markAsDirty({onlySelf}?: {
markAsDirty(opts?: {
onlySelf?: boolean;
}): void;
markAsPending({onlySelf}?: {
markAsPending(opts?: {
onlySelf?: boolean;
}): void;
markAsPristine({onlySelf}?: {
markAsPristine(opts?: {
onlySelf?: boolean;
}): void;
markAsTouched({onlySelf}?: {
markAsTouched(opts?: {
onlySelf?: boolean;
}): void;
markAsUntouched({onlySelf}?: {
markAsUntouched(opts?: {
onlySelf?: boolean;
}): void;
abstract patchValue(value: any, options?: Object): void;
abstract reset(value?: any, options?: Object): void;
setAsyncValidators(newValidator: AsyncValidatorFn | AsyncValidatorFn[]): void;
setErrors(errors: ValidationErrors | null, {emitEvent}?: {
setErrors(errors: ValidationErrors | null, opts?: {
emitEvent?: boolean;
}): void;
setParent(parent: FormGroup | FormArray): void;
setValidators(newValidator: ValidatorFn | ValidatorFn[] | null): void;
abstract setValue(value: any, options?: Object): void;
updateValueAndValidity({onlySelf, emitEvent}?: {
updateValueAndValidity(opts?: {
onlySelf?: boolean;
emitEvent?: boolean;
}): void;

View File

@ -259,7 +259,7 @@ export declare class Router {
readonly url: string;
urlHandlingStrategy: UrlHandlingStrategy;
constructor(rootComponentType: Type<any> | null, urlSerializer: UrlSerializer, rootContexts: ChildrenOutletContexts, location: Location, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Routes);
createUrlTree(commands: any[], {relativeTo, queryParams, fragment, preserveQueryParams, queryParamsHandling, preserveFragment}?: NavigationExtras): UrlTree;
createUrlTree(commands: any[], navigationExtras?: NavigationExtras): UrlTree;
dispose(): void;
initialNavigation(): void;
isActive(url: string | UrlTree, exact: boolean): boolean;