Skip to content

Commit c59c390

Browse files
alxhubhansl
authored andcommitted
fix: argument destructuring sometimes breaks strictNullChecks
Destructuring of the form: function foo({a, b}: {a?, b?} = {}) breaks strictNullChecks, due to the TypeScript bug microsoft/TypeScript#10078. This change eliminates usage of destructuring in function argument lists in cases where it would leak into the public API .d.ts.
1 parent 009651e commit c59c390

8 files changed

Lines changed: 91 additions & 97 deletions

File tree

packages/common/src/pipes/intl.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,15 @@ export enum NumberFormatStyle {
1313
}
1414

1515
export class NumberFormatter {
16-
static format(
17-
num: number, locale: string, style: NumberFormatStyle,
18-
{minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, currency,
19-
currencyAsSymbol = false}: {
20-
minimumIntegerDigits?: number,
21-
minimumFractionDigits?: number,
22-
maximumFractionDigits?: number,
23-
currency?: string|null,
24-
currencyAsSymbol?: boolean
25-
} = {}): string {
16+
static format(num: number, locale: string, style: NumberFormatStyle, opts: {
17+
minimumIntegerDigits?: number,
18+
minimumFractionDigits?: number,
19+
maximumFractionDigits?: number,
20+
currency?: string|null,
21+
currencyAsSymbol?: boolean
22+
} = {}): string {
23+
const {minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, currency,
24+
currencyAsSymbol = false} = opts;
2625
const options: Intl.NumberFormatOptions = {
2726
minimumIntegerDigits,
2827
minimumFractionDigits,

packages/core/src/metadata/di.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,8 @@ export interface ContentChildrenDecorator {
183183
* @stable
184184
* @Annotation
185185
*/
186-
(selector: Type<any>|Function|string,
187-
{descendants, read}?: {descendants?: boolean, read?: any}): any;
188-
new (
189-
selector: Type<any>|Function|string,
190-
{descendants, read}?: {descendants?: boolean, read?: any}): Query;
186+
(selector: Type<any>|Function|string, opts?: {descendants?: boolean, read?: any}): any;
187+
new (selector: Type<any>|Function|string, opts?: {descendants?: boolean, read?: any}): Query;
191188
}
192189

193190
/**
@@ -247,8 +244,8 @@ export interface ContentChildDecorator {
247244
* @stable
248245
* @Annotation
249246
*/
250-
(selector: Type<any>|Function|string, {read}?: {read?: any}): any;
251-
new (selector: Type<any>|Function|string, {read}?: {read?: any}): ContentChild;
247+
(selector: Type<any>|Function|string, opts?: {read?: any}): any;
248+
new (selector: Type<any>|Function|string, opts?: {read?: any}): ContentChild;
252249
}
253250

254251
/**
@@ -308,8 +305,8 @@ export interface ViewChildrenDecorator {
308305
* @stable
309306
* @Annotation
310307
*/
311-
(selector: Type<any>|Function|string, {read}?: {read?: any}): any;
312-
new (selector: Type<any>|Function|string, {read}?: {read?: any}): ViewChildren;
308+
(selector: Type<any>|Function|string, opts?: {read?: any}): any;
309+
new (selector: Type<any>|Function|string, opts?: {read?: any}): ViewChildren;
313310
}
314311

315312
/**
@@ -365,8 +362,8 @@ export interface ViewChildDecorator {
365362
* @stable
366363
* @Annotation
367364
*/
368-
(selector: Type<any>|Function|string, {read}?: {read?: any}): any;
369-
new (selector: Type<any>|Function|string, {read}?: {read?: any}): ViewChild;
365+
(selector: Type<any>|Function|string, opts?: {read?: any}): any;
366+
new (selector: Type<any>|Function|string, opts?: {read?: any}): ViewChild;
370367
}
371368

372369
/**

packages/core/src/metadata/view.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,21 @@ export class ViewMetadata {
7676
/** {@link Component#interpolation} */
7777
interpolation: [string, string]|undefined;
7878

79-
constructor(
80-
{templateUrl, template, encapsulation, styles, styleUrls, animations, interpolation}: {
81-
templateUrl?: string,
82-
template?: string,
83-
encapsulation?: ViewEncapsulation,
84-
styles?: string[],
85-
styleUrls?: string[],
86-
animations?: any[],
87-
interpolation?: [string, string]
88-
} = {}) {
89-
this.templateUrl = templateUrl;
90-
this.template = template;
91-
this.styleUrls = styleUrls;
92-
this.styles = styles;
93-
this.encapsulation = encapsulation;
94-
this.animations = animations;
95-
this.interpolation = interpolation;
79+
constructor(opts: {
80+
templateUrl?: string,
81+
template?: string,
82+
encapsulation?: ViewEncapsulation,
83+
styles?: string[],
84+
styleUrls?: string[],
85+
animations?: any[],
86+
interpolation?: [string, string]
87+
} = {}) {
88+
this.templateUrl = opts.templateUrl;
89+
this.template = opts.template;
90+
this.styleUrls = opts.styleUrls;
91+
this.styles = opts.styles;
92+
this.encapsulation = opts.encapsulation;
93+
this.animations = opts.animations;
94+
this.interpolation = opts.interpolation;
9695
}
9796
}

packages/forms/src/model.ts

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,11 @@ export abstract class AbstractControl {
238238
* This will also mark all direct ancestors as `touched` to maintain
239239
* the model.
240240
*/
241-
markAsTouched({onlySelf}: {onlySelf?: boolean} = {}): void {
241+
markAsTouched(opts: {onlySelf?: boolean} = {}): void {
242242
this._touched = true;
243243

244-
if (this._parent && !onlySelf) {
245-
this._parent.markAsTouched({onlySelf});
244+
if (this._parent && !opts.onlySelf) {
245+
this._parent.markAsTouched(opts);
246246
}
247247
}
248248

@@ -253,14 +253,14 @@ export abstract class AbstractControl {
253253
* to maintain the model, and re-calculate the `touched` status of all parent
254254
* controls.
255255
*/
256-
markAsUntouched({onlySelf}: {onlySelf?: boolean} = {}): void {
256+
markAsUntouched(opts: {onlySelf?: boolean} = {}): void {
257257
this._touched = false;
258258

259259
this._forEachChild(
260260
(control: AbstractControl) => { control.markAsUntouched({onlySelf: true}); });
261261

262-
if (this._parent && !onlySelf) {
263-
this._parent._updateTouched({onlySelf});
262+
if (this._parent && !opts.onlySelf) {
263+
this._parent._updateTouched(opts);
264264
}
265265
}
266266

@@ -270,11 +270,11 @@ export abstract class AbstractControl {
270270
* This will also mark all direct ancestors as `dirty` to maintain
271271
* the model.
272272
*/
273-
markAsDirty({onlySelf}: {onlySelf?: boolean} = {}): void {
273+
markAsDirty(opts: {onlySelf?: boolean} = {}): void {
274274
this._pristine = false;
275275

276-
if (this._parent && !onlySelf) {
277-
this._parent.markAsDirty({onlySelf});
276+
if (this._parent && !opts.onlySelf) {
277+
this._parent.markAsDirty(opts);
278278
}
279279
}
280280

@@ -285,24 +285,24 @@ export abstract class AbstractControl {
285285
* to maintain the model, and re-calculate the `pristine` status of all parent
286286
* controls.
287287
*/
288-
markAsPristine({onlySelf}: {onlySelf?: boolean} = {}): void {
288+
markAsPristine(opts: {onlySelf?: boolean} = {}): void {
289289
this._pristine = true;
290290

291291
this._forEachChild((control: AbstractControl) => { control.markAsPristine({onlySelf: true}); });
292292

293-
if (this._parent && !onlySelf) {
294-
this._parent._updatePristine({onlySelf});
293+
if (this._parent && !opts.onlySelf) {
294+
this._parent._updatePristine(opts);
295295
}
296296
}
297297

298298
/**
299299
* Marks the control as `pending`.
300300
*/
301-
markAsPending({onlySelf}: {onlySelf?: boolean} = {}): void {
301+
markAsPending(opts: {onlySelf?: boolean} = {}): void {
302302
this._status = PENDING;
303303

304-
if (this._parent && !onlySelf) {
305-
this._parent.markAsPending({onlySelf});
304+
if (this._parent && !opts.onlySelf) {
305+
this._parent.markAsPending(opts);
306306
}
307307
}
308308

@@ -312,18 +312,18 @@ export abstract class AbstractControl {
312312
*
313313
* If the control has children, all children will be disabled to maintain the model.
314314
*/
315-
disable({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
315+
disable(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
316316
this._status = DISABLED;
317317
this._errors = null;
318318
this._forEachChild((control: AbstractControl) => { control.disable({onlySelf: true}); });
319319
this._updateValue();
320320

321-
if (emitEvent !== false) {
321+
if (opts.emitEvent !== false) {
322322
this._valueChanges.emit(this._value);
323323
this._statusChanges.emit(this._status);
324324
}
325325

326-
this._updateAncestors(!!onlySelf);
326+
this._updateAncestors(!!opts.onlySelf);
327327
this._onDisabledChange.forEach((changeFn) => changeFn(true));
328328
}
329329

@@ -334,12 +334,12 @@ export abstract class AbstractControl {
334334
*
335335
* If the control has children, all children will be enabled.
336336
*/
337-
enable({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
337+
enable(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
338338
this._status = VALID;
339339
this._forEachChild((control: AbstractControl) => { control.enable({onlySelf: true}); });
340-
this.updateValueAndValidity({onlySelf: true, emitEvent});
340+
this.updateValueAndValidity({onlySelf: true, emitEvent: opts.emitEvent});
341341

342-
this._updateAncestors(!!onlySelf);
342+
this._updateAncestors(!!opts.onlySelf);
343343
this._onDisabledChange.forEach((changeFn) => changeFn(false));
344344
}
345345

@@ -373,8 +373,7 @@ export abstract class AbstractControl {
373373
*
374374
* By default, it will also update the value and validity of its ancestors.
375375
*/
376-
updateValueAndValidity({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
377-
void {
376+
updateValueAndValidity(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
378377
this._setInitialStatus();
379378
this._updateValue();
380379

@@ -384,24 +383,24 @@ export abstract class AbstractControl {
384383
this._status = this._calculateStatus();
385384

386385
if (this._status === VALID || this._status === PENDING) {
387-
this._runAsyncValidator(emitEvent);
386+
this._runAsyncValidator(opts.emitEvent);
388387
}
389388
}
390389

391-
if (emitEvent !== false) {
390+
if (opts.emitEvent !== false) {
392391
this._valueChanges.emit(this._value);
393392
this._statusChanges.emit(this._status);
394393
}
395394

396-
if (this._parent && !onlySelf) {
397-
this._parent.updateValueAndValidity({onlySelf, emitEvent});
395+
if (this._parent && !opts.onlySelf) {
396+
this._parent.updateValueAndValidity(opts);
398397
}
399398
}
400399

401400
/** @internal */
402-
_updateTreeValidity({emitEvent}: {emitEvent?: boolean} = {emitEvent: true}) {
403-
this._forEachChild((ctrl: AbstractControl) => ctrl._updateTreeValidity({emitEvent}));
404-
this.updateValueAndValidity({onlySelf: true, emitEvent});
401+
_updateTreeValidity(opts: {emitEvent?: boolean} = {emitEvent: true}) {
402+
this._forEachChild((ctrl: AbstractControl) => ctrl._updateTreeValidity(opts));
403+
this.updateValueAndValidity({onlySelf: true, emitEvent: opts.emitEvent});
405404
}
406405

407406
private _setInitialStatus() { this._status = this._allControlsDisabled() ? DISABLED : VALID; }
@@ -448,9 +447,9 @@ export abstract class AbstractControl {
448447
* expect(login.valid).toEqual(true);
449448
* ```
450449
*/
451-
setErrors(errors: ValidationErrors|null, {emitEvent}: {emitEvent?: boolean} = {}): void {
450+
setErrors(errors: ValidationErrors|null, opts: {emitEvent?: boolean} = {}): void {
452451
this._errors = errors;
453-
this._updateControlsErrors(emitEvent !== false);
452+
this._updateControlsErrors(opts.emitEvent !== false);
454453
}
455454

456455
/**
@@ -556,20 +555,20 @@ export abstract class AbstractControl {
556555
}
557556

558557
/** @internal */
559-
_updatePristine({onlySelf}: {onlySelf?: boolean} = {}): void {
558+
_updatePristine(opts: {onlySelf?: boolean} = {}): void {
560559
this._pristine = !this._anyControlsDirty();
561560

562-
if (this._parent && !onlySelf) {
563-
this._parent._updatePristine({onlySelf});
561+
if (this._parent && !opts.onlySelf) {
562+
this._parent._updatePristine(opts);
564563
}
565564
}
566565

567566
/** @internal */
568-
_updateTouched({onlySelf}: {onlySelf?: boolean} = {}): void {
567+
_updateTouched(opts: {onlySelf?: boolean} = {}): void {
569568
this._touched = this._anyControlsTouched();
570569

571-
if (this._parent && !onlySelf) {
572-
this._parent._updateTouched({onlySelf});
570+
if (this._parent && !opts.onlySelf) {
571+
this._parent._updateTouched(opts);
573572
}
574573
}
575574

packages/router/src/router.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,9 @@ export class Router {
385385
* router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
386386
* ```
387387
*/
388-
createUrlTree(
389-
commands: any[], {relativeTo, queryParams, fragment, preserveQueryParams, queryParamsHandling,
390-
preserveFragment}: NavigationExtras = {}): UrlTree {
388+
createUrlTree(commands: any[], navigationExtras: NavigationExtras = {}): UrlTree {
389+
const {relativeTo, queryParams, fragment,
390+
preserveQueryParams, queryParamsHandling, preserveFragment} = navigationExtras;
391391
if (isDevMode() && preserveQueryParams && <any>console && <any>console.warn) {
392392
console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
393393
}

tools/public_api_guard/core/core.d.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,10 @@ export declare const ContentChild: ContentChildDecorator;
262262

263263
/** @stable */
264264
export interface ContentChildDecorator {
265-
/** @stable */ (selector: Type<any> | Function | string, {read}?: {
265+
/** @stable */ (selector: Type<any> | Function | string, opts?: {
266266
read?: any;
267267
}): any;
268-
new (selector: Type<any> | Function | string, {read}?: {
268+
new (selector: Type<any> | Function | string, opts?: {
269269
read?: any;
270270
}): ContentChild;
271271
}
@@ -275,11 +275,11 @@ export declare const ContentChildren: ContentChildrenDecorator;
275275

276276
/** @stable */
277277
export interface ContentChildrenDecorator {
278-
/** @stable */ (selector: Type<any> | Function | string, {descendants, read}?: {
278+
/** @stable */ (selector: Type<any> | Function | string, opts?: {
279279
descendants?: boolean;
280280
read?: any;
281281
}): any;
282-
new (selector: Type<any> | Function | string, {descendants, read}?: {
282+
new (selector: Type<any> | Function | string, opts?: {
283283
descendants?: boolean;
284284
read?: any;
285285
}): Query;
@@ -1058,10 +1058,10 @@ export declare const ViewChild: ViewChildDecorator;
10581058

10591059
/** @stable */
10601060
export interface ViewChildDecorator {
1061-
/** @stable */ (selector: Type<any> | Function | string, {read}?: {
1061+
/** @stable */ (selector: Type<any> | Function | string, opts?: {
10621062
read?: any;
10631063
}): any;
1064-
new (selector: Type<any> | Function | string, {read}?: {
1064+
new (selector: Type<any> | Function | string, opts?: {
10651065
read?: any;
10661066
}): ViewChild;
10671067
}
@@ -1071,10 +1071,10 @@ export declare const ViewChildren: ViewChildrenDecorator;
10711071

10721072
/** @stable */
10731073
export interface ViewChildrenDecorator {
1074-
/** @stable */ (selector: Type<any> | Function | string, {read}?: {
1074+
/** @stable */ (selector: Type<any> | Function | string, opts?: {
10751075
read?: any;
10761076
}): any;
1077-
new (selector: Type<any> | Function | string, {read}?: {
1077+
new (selector: Type<any> | Function | string, opts?: {
10781078
read?: any;
10791079
}): ViewChildren;
10801080
}

0 commit comments

Comments
 (0)