fix(common): Update types for TypeScript nullability support

This commit is contained in:
Miško Hevery
2017-03-24 09:54:02 -07:00
committed by Hans
parent 4c566dbfbb
commit d8b73e4223
29 changed files with 126 additions and 117 deletions

View File

@ -38,8 +38,8 @@ import {Directive, DoCheck, ElementRef, Input, IterableChanges, IterableDiffer,
*/
@Directive({selector: '[ngClass]'})
export class NgClass implements DoCheck {
private _iterableDiffer: IterableDiffer<string>;
private _keyValueDiffer: KeyValueDiffer<string, any>;
private _iterableDiffer: IterableDiffer<string>|null;
private _keyValueDiffer: KeyValueDiffer<string, any>|null;
private _initialClasses: string[] = [];
private _rawClass: string[]|Set<string>|{[klass: string]: any};

View File

@ -73,8 +73,8 @@ export class NgComponentOutlet implements OnChanges, OnDestroy {
@Input() ngComponentOutletContent: any[][];
@Input() ngComponentOutletNgModuleFactory: NgModuleFactory<any>;
private _componentRef: ComponentRef<any> = null;
private _moduleRef: NgModuleRef<any> = null;
private _componentRef: ComponentRef<any>|null = null;
private _moduleRef: NgModuleRef<any>|null = null;
constructor(private _viewContainerRef: ViewContainerRef) {}

View File

@ -114,7 +114,7 @@ export class NgForOf<T> implements DoCheck, OnChanges {
get ngForTrackBy(): TrackByFunction<T> { return this._trackByFn; }
private _differ: IterableDiffer<T> = null;
private _differ: IterableDiffer<T>|null = null;
private _trackByFn: TrackByFunction<T>;
constructor(
@ -159,13 +159,13 @@ export class NgForOf<T> implements DoCheck, OnChanges {
(item: IterableChangeRecord<any>, adjustedPreviousIndex: number, currentIndex: number) => {
if (item.previousIndex == null) {
const view = this._viewContainer.createEmbeddedView(
this._template, new NgForOfContext(null, this.ngForOf, null, null), currentIndex);
const tuple = new RecordViewTuple(item, view);
this._template, new NgForOfContext<T>(null !, this.ngForOf, -1, -1), currentIndex);
const tuple = new RecordViewTuple<T>(item, view);
insertTuples.push(tuple);
} else if (currentIndex == null) {
this._viewContainer.remove(adjustedPreviousIndex);
} else {
const view = this._viewContainer.get(adjustedPreviousIndex);
const view = this._viewContainer.get(adjustedPreviousIndex) !;
this._viewContainer.move(view, currentIndex);
const tuple = new RecordViewTuple(item, <EmbeddedViewRef<NgForOfContext<T>>>view);
insertTuples.push(tuple);

View File

@ -102,10 +102,10 @@ import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef} from '
@Directive({selector: '[ngIf]'})
export class NgIf {
private _context: NgIfContext = new NgIfContext();
private _thenTemplateRef: TemplateRef<NgIfContext> = null;
private _elseTemplateRef: TemplateRef<NgIfContext> = null;
private _thenViewRef: EmbeddedViewRef<NgIfContext> = null;
private _elseViewRef: EmbeddedViewRef<NgIfContext> = null;
private _thenTemplateRef: TemplateRef<NgIfContext>|null = null;
private _elseTemplateRef: TemplateRef<NgIfContext>|null = null;
private _thenViewRef: EmbeddedViewRef<NgIfContext>|null = null;
private _elseViewRef: EmbeddedViewRef<NgIfContext>|null = null;
constructor(private _viewContainer: ViewContainerRef, templateRef: TemplateRef<NgIfContext>) {
this._thenTemplateRef = templateRef;

View File

@ -61,7 +61,7 @@ export class NgStyle implements DoCheck {
changes.forEachChangedItem((record) => this._setStyle(record.key, record.currentValue));
}
private _setStyle(nameAndUnit: string, value: string|number): void {
private _setStyle(nameAndUnit: string, value: string|number|null|undefined): void {
const [name, unit] = nameAndUnit.split('.');
value = value != null && unit ? `${value}${unit}` : value;

View File

@ -66,7 +66,8 @@ export class HashLocationStrategy extends LocationStrategy {
}
pushState(state: any, title: string, path: string, queryParams: string) {
let url = this.prepareExternalUrl(path + Location.normalizeQueryParams(queryParams));
let url: string|null =
this.prepareExternalUrl(path + Location.normalizeQueryParams(queryParams));
if (url.length == 0) {
url = this._platformLocation.pathname;
}

View File

@ -128,8 +128,8 @@ export class Location {
* Subscribe to the platform's `popState` events.
*/
subscribe(
onNext: (value: PopStateEvent) => void, onThrow: (exception: any) => void = null,
onReturn: () => void = null): Object {
onNext: (value: PopStateEvent) => void, onThrow?: ((exception: any) => void)|null,
onReturn?: (() => void)|null): Object {
return this._subject.subscribe({next: onNext, error: onThrow, complete: onReturn});
}

View File

@ -38,9 +38,9 @@ export abstract class PlatformLocation {
abstract onPopState(fn: LocationChangeListener): void;
abstract onHashChange(fn: LocationChangeListener): void;
get pathname(): string { return null; }
get search(): string { return null; }
get hash(): string { return null; }
abstract get pathname(): string;
abstract get search(): string;
abstract get hash(): string;
abstract replaceState(state: any, title: string, url: string): void;

View File

@ -8,33 +8,34 @@
import {ChangeDetectorRef, EventEmitter, OnDestroy, Pipe, PipeTransform, WrappedValue, ɵisObservable, ɵisPromise} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {ISubscription} from 'rxjs/Subscription';
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
interface SubscriptionStrategy {
createSubscription(async: any, updateLatestValue: any): any;
dispose(subscription: any): void;
onDestroy(subscription: any): void;
createSubscription(async: Observable<any>|Promise<any>, updateLatestValue: any): ISubscription
|Promise<any>;
dispose(subscription: ISubscription|Promise<any>): void;
onDestroy(subscription: ISubscription|Promise<any>): void;
}
class ObservableStrategy implements SubscriptionStrategy {
createSubscription(async: any, updateLatestValue: any): any {
createSubscription(async: Observable<any>, updateLatestValue: any): ISubscription {
return async.subscribe({next: updateLatestValue, error: (e: any) => { throw e; }});
}
dispose(subscription: any): void { subscription.unsubscribe(); }
dispose(subscription: ISubscription): void { subscription.unsubscribe(); }
onDestroy(subscription: any): void { subscription.unsubscribe(); }
onDestroy(subscription: ISubscription): void { subscription.unsubscribe(); }
}
class PromiseStrategy implements SubscriptionStrategy {
createSubscription(async: Promise<any>, updateLatestValue: (v: any) => any): any {
createSubscription(async: Promise<any>, updateLatestValue: (v: any) => any): Promise<any> {
return async.then(updateLatestValue, e => { throw e; });
}
dispose(subscription: any): void {}
dispose(subscription: Promise<any>): void {}
onDestroy(subscription: any): void {}
onDestroy(subscription: Promise<any>): void {}
}
const _promiseStrategy = new PromiseStrategy();
@ -67,12 +68,12 @@ const _observableStrategy = new ObservableStrategy();
*/
@Pipe({name: 'async', pure: false})
export class AsyncPipe implements OnDestroy, PipeTransform {
private _latestValue: Object = null;
private _latestReturnedValue: Object = null;
private _latestValue: any = null;
private _latestReturnedValue: any = null;
private _subscription: Object = null;
private _obj: Observable<any>|Promise<any>|EventEmitter<any> = null;
private _strategy: SubscriptionStrategy = null;
private _subscription: ISubscription|Promise<any>|null = null;
private _obj: Observable<any>|Promise<any>|EventEmitter<any>|null = null;
private _strategy: SubscriptionStrategy = null !;
constructor(private _ref: ChangeDetectorRef) {}
@ -82,10 +83,11 @@ export class AsyncPipe implements OnDestroy, PipeTransform {
}
}
transform<T>(obj: null): null;
transform<T>(obj: undefined): undefined;
transform<T>(obj: Observable<T>): T|null;
transform<T>(obj: Promise<T>): T|null;
transform<T>(obj: EventEmitter<T>): T|null;
transform(obj: Observable<any>|Promise<any>|EventEmitter<any>): any {
transform(obj: Observable<any>|Promise<any>|null|undefined): any {
if (!this._obj) {
if (obj) {
this._subscribe(obj);
@ -127,7 +129,7 @@ export class AsyncPipe implements OnDestroy, PipeTransform {
}
private _dispose(): void {
this._strategy.dispose(this._subscription);
this._strategy.dispose(this._subscription !);
this._latestValue = null;
this._latestReturnedValue = null;
this._subscription = null;

View File

@ -100,7 +100,7 @@ export class DatePipe implements PipeTransform {
constructor(@Inject(LOCALE_ID) private _locale: string) {}
transform(value: any, pattern: string = 'mediumDate'): string {
transform(value: any, pattern: string = 'mediumDate'): string|null {
let date: Date;
if (isBlank(value) || value !== value) return null;
@ -130,7 +130,7 @@ export class DatePipe implements PipeTransform {
}
if (!isDate(date)) {
let match: RegExpMatchArray;
let match: RegExpMatchArray|null;
if ((typeof value === 'string') && (match = value.match(ISO8601_DATE_REGEX))) {
date = isoStringToDate(match);
} else {

View File

@ -28,7 +28,7 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
*/
@Pipe({name: 'i18nSelect', pure: true})
export class I18nSelectPipe implements PipeTransform {
transform(value: string, mapping: {[key: string]: string}): string {
transform(value: string|null|undefined, mapping: {[key: string]: string}): string {
if (value == null) return '';
if (typeof mapping !== 'object' || typeof value !== 'string') {

View File

@ -20,7 +20,7 @@ export class NumberFormatter {
minimumIntegerDigits?: number,
minimumFractionDigits?: number,
maximumFractionDigits?: number,
currency?: string,
currency?: string|null,
currencyAsSymbol?: boolean
} = {}): string {
const options: Intl.NumberFormatOptions = {
@ -31,7 +31,7 @@ export class NumberFormatter {
};
if (style == NumberFormatStyle.Currency) {
options.currency = currency;
options.currency = typeof currency == 'string' ? currency : undefined;
options.currencyDisplay = currencyAsSymbol ? 'symbol' : 'code';
}
return new Intl.NumberFormat(locale, options).format(num);
@ -192,17 +192,18 @@ function dateFormatter(format: string, date: Date, locale: string): string {
if (!parts) {
parts = [];
let match: RegExpExecArray;
let match: RegExpExecArray|null;
DATE_FORMATS_SPLIT.exec(format);
while (format) {
match = DATE_FORMATS_SPLIT.exec(format);
let _format: string|null = format;
while (_format) {
match = DATE_FORMATS_SPLIT.exec(_format);
if (match) {
parts = parts.concat(match.slice(1));
format = parts.pop();
_format = parts.pop() !;
} else {
parts.push(format);
format = null;
parts.push(_format);
_format = null;
}
}

View File

@ -14,7 +14,8 @@ const _NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;
function formatNumber(
pipe: Type<any>, locale: string, value: number | string, style: NumberFormatStyle,
digits: string, currency: string = null, currencyAsSymbol: boolean = false): string {
digits?: string | null, currency: string | null = null,
currencyAsSymbol: boolean = false): string|null {
if (value == null) return null;
// Convert strings to numbers
@ -23,9 +24,9 @@ function formatNumber(
throw invalidPipeArgumentError(pipe, value);
}
let minInt: number;
let minFraction: number;
let maxFraction: number;
let minInt: number|undefined = undefined;
let minFraction: number|undefined = undefined;
let maxFraction: number|undefined = undefined;
if (style !== NumberFormatStyle.Currency) {
// rely on Intl default for currency
minInt = 1;
@ -89,7 +90,7 @@ function formatNumber(
export class DecimalPipe implements PipeTransform {
constructor(@Inject(LOCALE_ID) private _locale: string) {}
transform(value: any, digits: string = null): string {
transform(value: any, digits?: string): string|null {
return formatNumber(DecimalPipe, this._locale, value, NumberFormatStyle.Decimal, digits);
}
}
@ -118,7 +119,7 @@ export class DecimalPipe implements PipeTransform {
export class PercentPipe implements PipeTransform {
constructor(@Inject(LOCALE_ID) private _locale: string) {}
transform(value: any, digits: string = null): string {
transform(value: any, digits?: string): string|null {
return formatNumber(PercentPipe, this._locale, value, NumberFormatStyle.Percent, digits);
}
}
@ -153,7 +154,7 @@ export class CurrencyPipe implements PipeTransform {
transform(
value: any, currencyCode: string = 'USD', symbolDisplay: boolean = false,
digits: string = null): string {
digits?: string): string|null {
return formatNumber(
CurrencyPipe, this._locale, value, NumberFormatStyle.Currency, digits, currencyCode,
symbolDisplay);