fix: turn on nullability in the code base.

This commit is contained in:
Miško Hevery 2017-04-14 14:40:56 -07:00 committed by Tobias Bosch
parent 728c9d0632
commit 5293794316
27 changed files with 67 additions and 70 deletions

View File

@ -35,7 +35,7 @@ export function main() {
});
it('should be marked as pure',
() => { expect(new PipeResolver().resolve(DatePipe).pure).toEqual(true); });
() => { expect(new PipeResolver().resolve(DatePipe) !.pure).toEqual(true); });
describe('supports', () => {
it('should support date', () => { expect(() => pipe.transform(date)).not.toThrow(); });

View File

@ -28,7 +28,7 @@ export function main() {
});
it('should be marked as pure',
() => { expect(new PipeResolver().resolve(I18nPluralPipe).pure).toEqual(true); });
() => { expect(new PipeResolver().resolve(I18nPluralPipe) !.pure).toEqual(true); });
describe('transform', () => {
it('should return 0 text if value is 0', () => {

View File

@ -15,7 +15,7 @@ export function main() {
const mapping = {'male': 'Invite him.', 'female': 'Invite her.', 'other': 'Invite them.'};
it('should be marked as pure',
() => { expect(new PipeResolver().resolve(I18nSelectPipe).pure).toEqual(true); });
() => { expect(new PipeResolver().resolve(I18nSelectPipe) !.pure).toEqual(true); });
describe('transform', () => {
it('should return the "male" text if value is "male"', () => {

View File

@ -20,12 +20,12 @@ export class MockAotContext implements CompilerHostContext {
directoryExists(path: string): boolean { return typeof this.getEntry(path) === 'object'; }
readFile(fileName: string): string|undefined {
readFile(fileName: string): string {
const data = this.getEntry(fileName);
if (typeof data === 'string') {
return data;
}
return undefined;
return undefined !;
}
readResource(fileName: string): Promise<string> {
@ -38,7 +38,7 @@ export class MockAotContext implements CompilerHostContext {
writeFile(fileName: string, data: string): void {
const parts = fileName.split('/');
const name = parts.pop();
const name = parts.pop() !;
const entry = this.getEntry(parts);
if (entry && typeof entry !== 'string') {
entry[name] = data;
@ -56,7 +56,7 @@ export class MockAotContext implements CompilerHostContext {
parts = normalize(parts);
let current = this.files;
while (parts.length) {
const part = parts.shift();
const part = parts.shift() !;
if (typeof current === 'string') {
return undefined;
}
@ -82,7 +82,7 @@ export class MockAotContext implements CompilerHostContext {
function normalize(parts: string[]): string[] {
const result: string[] = [];
while (parts.length) {
const part = parts.shift();
const part = parts.shift() !;
switch (part) {
case '.':
break;
@ -114,7 +114,7 @@ export class MockCompilerHost implements ts.CompilerHost {
if (sourceText) {
return ts.createSourceFile(fileName, sourceText, languageVersion);
} else {
return undefined;
return undefined !;
}
}

View File

@ -437,7 +437,7 @@ export class MockStaticSymbolResolverHost implements StaticSymbolResolverHost {
return baseName + '.d.ts';
}
if (modulePath == 'unresolved') {
return undefined;
return undefined !;
}
return '/tmp/' + modulePath + '.d.ts';
}

View File

@ -366,9 +366,9 @@ export class MockAotCompilerHost implements AotCompilerHost {
tsFilesOnly() { this.dtsAreSource = false; }
// StaticSymbolResolverHost
getMetadataFor(modulePath: string): {[key: string]: any}[]|null {
getMetadataFor(modulePath: string): {[key: string]: any}[]|undefined {
if (!this.tsHost.fileExists(modulePath)) {
return null;
return undefined;
}
if (DTS.test(modulePath)) {
if (this.metadataVisible) {
@ -383,7 +383,7 @@ export class MockAotCompilerHost implements AotCompilerHost {
const metadata = this.metadataCollector.getMetadata(sf);
return metadata ? [metadata] : [];
}
return null;
return undefined;
}
moduleNameToFileName(moduleName: string, containingFile: string): string|null {

View File

@ -142,7 +142,7 @@ function normalizeLoadedTemplate(
styleUrls: o.styleUrls || [],
interpolation: o.interpolation || null,
encapsulation: o.encapsulation || null,
animations: o.animations || null,
animations: o.animations || [],
},
template, templateAbsUrl);
}

View File

@ -55,10 +55,10 @@ export function main() {
expect(meta.hostListeners).toEqual({'someHostListener': 'someHostListenerExpr'});
expect(meta.hostProperties).toEqual({'someHostProp': 'someHostPropExpr'});
expect(meta.hostAttributes).toEqual({'someHostAttr': 'someHostAttrValue'});
expect(meta.template.encapsulation).toBe(ViewEncapsulation.Emulated);
expect(meta.template.styles).toEqual(['someStyle']);
expect(meta.template.template).toEqual('someTemplate');
expect(meta.template.interpolation).toEqual(['{{', '}}']);
expect(meta.template !.encapsulation).toBe(ViewEncapsulation.Emulated);
expect(meta.template !.styles).toEqual(['someStyle']);
expect(meta.template !.template).toEqual('someTemplate');
expect(meta.template !.interpolation).toEqual(['{{', '}}']);
}));
it('should throw when reading metadata for component with external resources when sync=true is passed',
@ -84,9 +84,9 @@ export function main() {
resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, false).then(() => {
const meta = resolver.getDirectiveMetadata(ComponentWithExternalResources);
expect(meta.selector).toEqual('someSelector');
expect(meta.template.styleUrls).toEqual(['someStyleUrl']);
expect(meta.template.templateUrl).toEqual('someTemplateUrl');
expect(meta.template.template).toEqual('someTemplate');
expect(meta.template !.styleUrls).toEqual(['someStyleUrl']);
expect(meta.template !.templateUrl).toEqual('someTemplateUrl');
expect(meta.template !.template).toEqual('someTemplate');
});
resourceLoader.flush();
})));
@ -104,7 +104,7 @@ export function main() {
resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, false).then(() => {
const value: string =
resolver.getDirectiveMetadata(ComponentWithoutModuleId).template.templateUrl;
resolver.getDirectiveMetadata(ComponentWithoutModuleId).template !.templateUrl !;
const expectedEndValue = './someUrl';
expect(value.endsWith(expectedEndValue)).toBe(true);
});

View File

@ -14,9 +14,3 @@
export * from './src/core';
// This file only reexports content of the `src` folder. Keep it that way.
// This is a hack to prevent people from turning on strictNullChecks. See #15432
export declare interface ɵStrictNullChecksNotSupported {
dontUseStrictNullChecksWithAngularYetSeeIssue15432: string|null;
[key: string]: string;
}

View File

@ -89,7 +89,7 @@ export function createPlatform(injector: Injector): PlatformRef {
}
_platform = injector.get(PlatformRef);
const inits = injector.get(PLATFORM_INITIALIZER, null);
if (inits) inits.forEach(init => init());
if (inits) inits.forEach((init: any) => init());
return _platform;
}

View File

@ -121,7 +121,8 @@ export class DefaultKeyValueDiffer<K, V> implements KeyValueDiffer<K, V>, KeyVal
this._removalsHead = insertBefore;
for (let record = insertBefore; record !== null; record = record._nextRemoved) {
for (let record: KeyValueChangeRecord_<K, V>|null = insertBefore; record !== null;
record = record._nextRemoved) {
if (record === this._mapHead) {
this._mapHead = null;
}
@ -150,8 +151,8 @@ export class DefaultKeyValueDiffer<K, V> implements KeyValueDiffer<K, V>, KeyVal
* - The return value is the new value for the insertion pointer.
*/
private _insertBeforeOrAppend(
before: KeyValueChangeRecord_<K, V>,
record: KeyValueChangeRecord_<K, V>): KeyValueChangeRecord_<K, V> {
before: KeyValueChangeRecord_<K, V>|null,
record: KeyValueChangeRecord_<K, V>): KeyValueChangeRecord_<K, V>|null {
if (before) {
const prev = before._prev;
record._next = before;
@ -181,7 +182,7 @@ export class DefaultKeyValueDiffer<K, V> implements KeyValueDiffer<K, V>, KeyVal
private _getOrCreateRecordForKey(key: K, value: V): KeyValueChangeRecord_<K, V> {
if (this._records.has(key)) {
const record = this._records.get(key);
const record = this._records.get(key) !;
this._maybeAddToChanges(record, value);
const prev = record._prev;
const next = record._next;

View File

@ -30,7 +30,5 @@ export enum SecurityContext {
* @stable
*/
export abstract class Sanitizer {
abstract sanitize(context: SecurityContext, value: null): null;
abstract sanitize(context: SecurityContext, value: {}|string): string;
abstract sanitize(context: SecurityContext, value: {}|string|null): string|null;
}

View File

@ -273,7 +273,8 @@ function setElementClass(view: ViewData, renderNode: any, name: string, value: b
function setElementStyle(
view: ViewData, binding: BindingDef, renderNode: any, name: string, value: any) {
let renderValue: string|null = view.root.sanitizer.sanitize(SecurityContext.STYLE, value);
let renderValue: string|null =
view.root.sanitizer.sanitize(SecurityContext.STYLE, value as{} | string);
if (renderValue != null) {
renderValue = renderValue.toString();
const unit = binding.suffix;

View File

@ -127,7 +127,7 @@ function declareTests({useJit}: {useJit: boolean}) {
function createModule<T>(
moduleType: Type<T>, parentInjector?: Injector | null): NgModuleRef<T> {
return compiler.compileModuleSync(moduleType).create(parentInjector);
return compiler.compileModuleSync(moduleType).create(parentInjector || null);
}
function createComp<T>(compType: Type<T>, moduleType: Type<any>): ComponentFixture<T> {

View File

@ -81,7 +81,7 @@ export class ComponentFixture<T> {
// Do this check in the next tick so that ngZone gets a chance to update the state of
// pending macrotasks.
scheduleMicroTask(() => {
if (!this.ngZone.hasPendingMacrotasks) {
if (!ngZone.hasPendingMacrotasks) {
if (this._promise !== null) {
this._resolve !(true);
this._resolve = null;
@ -141,7 +141,7 @@ export class ComponentFixture<T> {
* Return whether the fixture is currently stable or has async tasks that have not been completed
* yet.
*/
isStable(): boolean { return this._isStable && !this.ngZone.hasPendingMacrotasks; }
isStable(): boolean { return this._isStable && !this.ngZone !.hasPendingMacrotasks; }
/**
* Get a promise that resolves when the fixture is stable.

View File

@ -4,6 +4,7 @@
"declaration": true,
"stripInternal": true,
"experimentalDecorators": true,
"strictNullChecks": true,
"module": "es2015",
"moduleResolution": "node",
"outDir": "../../dist/packages/core",

View File

@ -211,7 +211,7 @@ describe('diagnostics', () => {
export class MyComponent {}
`,
fileName => {
const diagnostics = ngService.getDiagnostics(fileName);
const diagnostics = ngService.getDiagnostics(fileName) !;
const expected = diagnostics.find(d => d.message.startsWith('Invalid providers for'));
const notExpected = diagnostics.find(d => d.message.startsWith('Cannot read property'));
expect(expected).toBeDefined();
@ -233,7 +233,7 @@ describe('diagnostics', () => {
})
export class MyComponent {}
`,
fileName => expectOnlyModuleDiagnostics(ngService.getDiagnostics(fileName)));
fileName => expectOnlyModuleDiagnostics(ngService.getDiagnostics(fileName) !));
});
// Issue #15625
@ -253,7 +253,7 @@ describe('diagnostics', () => {
}
`,
fileName => {
const diagnostics = ngService.getDiagnostics(fileName);
const diagnostics = ngService.getDiagnostics(fileName) !;
expectOnlyModuleDiagnostics(diagnostics);
});
});
@ -323,8 +323,9 @@ describe('diagnostics', () => {
}
}
function expectOnlyModuleDiagnostics(diagnostics: Diagnostics) {
function expectOnlyModuleDiagnostics(diagnostics: Diagnostics | undefined) {
// Expect only the 'MyComponent' diagnostic
if (!diagnostics) throw new Error('Expecting Diagnostics');
expect(diagnostics.length).toBe(1);
if (diagnostics.length > 1) {
for (const diagnostic of diagnostics) {

View File

@ -15,6 +15,6 @@ export {NgProbeToken} from './dom/debug/ng_probe';
export {DOCUMENT} from './dom/dom_tokens';
export {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager';
export {HAMMER_GESTURE_CONFIG, HammerGestureConfig} from './dom/events/hammer_gestures';
export {DomSanitizer, SafeHtml, SafeResourceUrl, SafeScript, SafeStyle, SafeUrl} from './security/dom_sanitization_service';
export {DomSanitizer, SafeHtml, SafeResourceUrl, SafeScript, SafeStyle, SafeUrl, SafeValue} from './security/dom_sanitization_service';
export * from './private_export';
export {VERSION} from './version';

View File

@ -100,8 +100,6 @@ export abstract class DomSanitizer implements Sanitizer {
* by replacing URLs that have an unsafe protocol part (such as `javascript:`). The implementation
* is responsible to make sure that the value can definitely be safely used in the given context.
*/
abstract sanitize(context: SecurityContext, value: null): null;
abstract sanitize(context: SecurityContext, value: SafeValue|string): string;
abstract sanitize(context: SecurityContext, value: SafeValue|string|null): string|null;
/**
@ -154,14 +152,11 @@ export abstract class DomSanitizer implements Sanitizer {
export class DomSanitizerImpl extends DomSanitizer {
constructor(@Inject(DOCUMENT) private _doc: any) { super(); }
sanitize(context: SecurityContext, value: null): null;
sanitize(context: SecurityContext, value: SafeValue|string): string;
sanitize(context: SecurityContext, value: SafeValue|string|null): string|null;
sanitize(ctx: SecurityContext, value: any): string|null {
sanitize(ctx: SecurityContext, value: SafeValue|string|null): string|null {
if (value == null) return null;
switch (ctx) {
case SecurityContext.NONE:
return value;
return value as string;
case SecurityContext.HTML:
if (value instanceof SafeHtmlImpl) return value.changingThisBreaksApplicationSecurity;
this.checkNotSafeValue(value, 'HTML');
@ -169,7 +164,7 @@ export class DomSanitizerImpl extends DomSanitizer {
case SecurityContext.STYLE:
if (value instanceof SafeStyleImpl) return value.changingThisBreaksApplicationSecurity;
this.checkNotSafeValue(value, 'Style');
return sanitizeStyle(value);
return sanitizeStyle(value as string);
case SecurityContext.SCRIPT:
if (value instanceof SafeScriptImpl) return value.changingThisBreaksApplicationSecurity;
this.checkNotSafeValue(value, 'Script');

View File

@ -121,7 +121,7 @@ _global.beforeEach(function() {
}
};
function compareMap(actual: any, expected: any): boolean|undefined {
function compareMap(actual: any, expected: any): boolean {
if (actual instanceof Map) {
let pass = actual.size === expected.size;
if (pass) {
@ -129,7 +129,8 @@ _global.beforeEach(function() {
}
return pass;
} else {
return undefined;
// TODO(misko): we should change the return, but jasmine.d.ts is not null safe
return undefined !;
}
}
},

View File

@ -3050,12 +3050,12 @@ describe('Integration', () => {
advance(fixture);
const config = router.config;
const firstConfig = config[1]._loadedConfig;
const firstConfig = config[1]._loadedConfig !;
expect(firstConfig).toBeDefined();
expect(firstConfig.routes[0].path).toEqual('LoadedModule1');
const secondConfig = firstConfig.routes[0]._loadedConfig;
const secondConfig = firstConfig.routes[0]._loadedConfig !;
expect(secondConfig).toBeDefined();
expect(secondConfig.routes[0].path).toEqual('LoadedModule2');
})));

View File

@ -97,12 +97,12 @@ describe('RouterPreloader', () => {
const c = router.config;
expect(c[0].loadChildren).toEqual('expected');
const loadedConfig: LoadedRouterConfig = c[0]._loadedConfig;
const loadedConfig: LoadedRouterConfig = c[0]._loadedConfig !;
const module: any = loadedConfig.module;
expect(loadedConfig.routes[0].path).toEqual('LoadedModule1');
expect(module.parent).toBe(testModule);
const loadedConfig2: LoadedRouterConfig = loadedConfig.routes[0]._loadedConfig;
const loadedConfig2: LoadedRouterConfig = loadedConfig.routes[0]._loadedConfig !;
const module2: any = loadedConfig2.module;
expect(loadedConfig2.routes[0].path).toEqual('LoadedModule2');
expect(module2.parent).toBe(module);
@ -165,12 +165,12 @@ describe('RouterPreloader', () => {
const c = router.config;
const loadedConfig: LoadedRouterConfig = c[0]._loadedConfig;
const loadedConfig: LoadedRouterConfig = c[0]._loadedConfig !;
const module: any = loadedConfig.module;
expect(module.parent).toBe(testModule);
const loadedConfig2: LoadedRouterConfig = loadedConfig.routes[0]._loadedConfig;
const loadedConfig3: LoadedRouterConfig = loadedConfig2.routes[0]._loadedConfig;
const loadedConfig2: LoadedRouterConfig = loadedConfig.routes[0]._loadedConfig !;
const loadedConfig3: LoadedRouterConfig = loadedConfig2.routes[0]._loadedConfig !;
const module3: any = loadedConfig3.module;
expect(module3.parent).toBe(module2);
})));

View File

@ -6,7 +6,7 @@
"emitDecoratorMetadata": true,
"module": "commonjs",
"moduleResolution": "node",
"strictNullChecks": false,
"strictNullChecks": true,
"outDir": "../dist/all/@angular",
"noImplicitAny": true,
"noFallthroughCasesInSwitch": true,

View File

@ -207,7 +207,8 @@ let angular: {
void,
module: (prefix: string, dependencies?: string[]) => IModule,
element: (e: Element | string) => IAugmentedJQuery,
version: {major: number}, resumeBootstrap?: () => void,
version: {major: number},
resumeBootstrap: () => void,
getTestability: (e: Element) => ITestabilityService
} = <any>{
bootstrap: noNg,

View File

@ -341,7 +341,7 @@ export declare class DebugNode {
/** @deprecated */
export declare class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChanges<V> {
readonly collection: NgIterable<V>;
readonly collection: V[] | Iterable<V> | null;
readonly isDirty: boolean;
readonly length: number;
constructor(trackByFn?: TrackByFunction<V>);
@ -716,7 +716,7 @@ export declare const PLATFORM_ID: InjectionToken<Object>;
export declare const PLATFORM_INITIALIZER: InjectionToken<(() => void)[]>;
/** @experimental */
export declare const platformCore: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformCore: (extraProviders?: Provider[] | undefined) => PlatformRef;
/** @stable */
export declare abstract class PlatformRef {
@ -891,7 +891,7 @@ export declare abstract class RootRenderer {
/** @stable */
export declare abstract class Sanitizer {
abstract sanitize(context: SecurityContext, value: string): string | null;
abstract sanitize(context: SecurityContext, value: {} | string | null): string | null;
}
/** @experimental */

View File

@ -26,7 +26,7 @@ export declare abstract class DomSanitizer implements Sanitizer {
abstract bypassSecurityTrustScript(value: string): SafeScript;
abstract bypassSecurityTrustStyle(value: string): SafeStyle;
abstract bypassSecurityTrustUrl(value: string): SafeUrl;
abstract sanitize(context: SecurityContext, value: any): string | null;
abstract sanitize(context: SecurityContext, value: SafeValue | string | null): string | null;
}
/** @experimental */
@ -112,6 +112,10 @@ export interface SafeStyle extends SafeValue {
export interface SafeUrl extends SafeValue {
}
/** @stable */
export interface SafeValue {
}
/** @experimental */
export declare class Title {
constructor(_doc: any);

View File

@ -135,9 +135,9 @@ export interface NavigationExtras {
fragment?: string;
preserveFragment?: boolean;
/** @deprecated */ preserveQueryParams?: boolean;
queryParams?: Params;
queryParamsHandling?: QueryParamsHandling;
relativeTo?: ActivatedRoute;
queryParams?: Params | null;
queryParamsHandling?: QueryParamsHandling | null;
relativeTo?: ActivatedRoute | null;
replaceUrl?: boolean;
skipLocationChange?: boolean;
}