build(bazel): Turning on strictPropertyInitialization for Angular. (#24572)

All errors for existing fields have been detected and suppressed with a
`!` assertion.

Issue/24571 is tracking proper clean up of those instances.

One-line change required in ivy/compilation.ts, because it appears that
the new syntax causes tsickle emitted node to no longer track their
original sourceFiles.

PR Close #24572
This commit is contained in:
Rado Kirov 2018-06-18 16:38:33 -07:00 committed by Miško Hevery
parent 39c7769c9e
commit c95437f15d
189 changed files with 1273 additions and 632 deletions

View File

@ -586,7 +586,8 @@ export class AnimationTimelineContext {
export class TimelineBuilder { export class TimelineBuilder {
public duration: number = 0; public duration: number = 0;
public easing: string|null; // TODO(issue/24571): remove '!'.
public easing !: string | null;
private _previousKeyframe: ɵStyleData = {}; private _previousKeyframe: ɵStyleData = {};
private _currentKeyframe: ɵStyleData = {}; private _currentKeyframe: ɵStyleData = {};
private _keyframes = new Map<number, ɵStyleData>(); private _keyframes = new Map<number, ɵStyleData>();

View File

@ -23,9 +23,11 @@ export class CssKeyframesPlayer implements AnimationPlayer {
private _onDestroyFns: Function[] = []; private _onDestroyFns: Function[] = [];
private _started = false; private _started = false;
private _styler: ElementAnimationStyleHandler; // TODO(issue/24571): remove '!'.
private _styler !: ElementAnimationStyleHandler;
public parentPlayer: AnimationPlayer; // TODO(issue/24571): remove '!'.
public parentPlayer !: AnimationPlayer;
public readonly totalTime: number; public readonly totalTime: number;
public readonly easing: string; public readonly easing: string;
public currentSnapshot: {[key: string]: string} = {}; public currentSnapshot: {[key: string]: string} = {};

View File

@ -1424,7 +1424,8 @@ export class TransitionAnimationPlayer implements AnimationPlayer {
private _queuedCallbacks: {[name: string]: (() => any)[]} = {}; private _queuedCallbacks: {[name: string]: (() => any)[]} = {};
public readonly destroyed = false; public readonly destroyed = false;
public parentPlayer: AnimationPlayer; // TODO(issue/24571): remove '!'.
public parentPlayer !: AnimationPlayer;
public markedForDestroy: boolean = false; public markedForDestroy: boolean = false;
public disabled = false; public disabled = false;

View File

@ -21,9 +21,11 @@ export class WebAnimationsPlayer implements AnimationPlayer {
private _finished = false; private _finished = false;
private _started = false; private _started = false;
private _destroyed = false; private _destroyed = false;
private _finalKeyframe: {[key: string]: string | number}; // TODO(issue/24571): remove '!'.
private _finalKeyframe !: {[key: string]: string | number};
public readonly domPlayer: DOMAnimation; // TODO(issue/24571): remove '!'.
public readonly domPlayer !: DOMAnimation;
public time = 0; public time = 0;
public parentPlayer: AnimationPlayer|null = null; public parentPlayer: AnimationPlayer|null = null;

View File

@ -12,8 +12,10 @@ const ParserUtil = require('./parser_util');
class Profiler { class Profiler {
private _profiler: any; private _profiler: any;
private _markerEvents: any[]; // TODO(issue/24571): remove '!'.
private _profilerStartTime: number; private _markerEvents !: any[];
// TODO(issue/24571): remove '!'.
private _profilerStartTime !: number;
constructor() { this._profiler = Cc['@mozilla.org/tools/profiler;1'].getService(Ci.nsIProfiler); } constructor() { this._profiler = Cc['@mozilla.org/tools/profiler;1'].getService(Ci.nsIProfiler); }

View File

@ -20,7 +20,8 @@ export class HttpHeaders {
/** /**
* Internal map of lowercase header names to values. * Internal map of lowercase header names to values.
*/ */
private headers: Map<string, string[]>; // TODO(issue/24571): remove '!'.
private headers !: Map<string, string[]>;
/** /**
@ -32,7 +33,8 @@ export class HttpHeaders {
/** /**
* Complete the lazy initialization of this object (needed before reading). * Complete the lazy initialization of this object (needed before reading).
*/ */
private lazyInit: HttpHeaders|Function|null; // TODO(issue/24571): remove '!'.
private lazyInit !: HttpHeaders | Function | null;
/** /**
* Queued updates to be materialized the next initialization. * Queued updates to be materialized the next initialization.

View File

@ -88,7 +88,8 @@ export class HttpRequest<T> {
/** /**
* Outgoing headers for this request. * Outgoing headers for this request.
*/ */
readonly headers: HttpHeaders; // TODO(issue/24571): remove '!'.
readonly headers !: HttpHeaders;
/** /**
* Whether this request should be made in a way that exposes progress events. * Whether this request should be made in a way that exposes progress events.
@ -119,7 +120,8 @@ export class HttpRequest<T> {
/** /**
* Outgoing URL parameters. * Outgoing URL parameters.
*/ */
readonly params: HttpParams; // TODO(issue/24571): remove '!'.
readonly params !: HttpParams;
/** /**
* The outgoing URL with all URL parameters set. * The outgoing URL with all URL parameters set.

View File

@ -171,7 +171,8 @@ export abstract class HttpResponseBase {
/** /**
* Type of the response, narrowed to either the full response or the header. * Type of the response, narrowed to either the full response or the header.
*/ */
readonly type: HttpEventType.Response|HttpEventType.ResponseHeader; // TODO(issue/24571): remove '!'.
readonly type !: HttpEventType.Response | HttpEventType.ResponseHeader;
/** /**
* Super-constructor for all responses. * Super-constructor for all responses.

View File

@ -22,7 +22,8 @@ export class MockScriptElement {
} }
export class MockDocument { export class MockDocument {
mock: MockScriptElement|null; // TODO(issue/24571): remove '!'.
mock !: MockScriptElement | null;
readonly body: any = this; readonly body: any = this;
createElement(tag: 'script'): HTMLScriptElement { createElement(tag: 'script'): HTMLScriptElement {

View File

@ -10,7 +10,8 @@ import {HttpHeaders} from '../src/headers';
import {XhrFactory} from '../src/xhr'; import {XhrFactory} from '../src/xhr';
export class MockXhrFactory implements XhrFactory { export class MockXhrFactory implements XhrFactory {
mock: MockXMLHttpRequest; // TODO(issue/24571): remove '!'.
mock !: MockXMLHttpRequest;
build(): XMLHttpRequest { return (this.mock = new MockXMLHttpRequest()) as any; } build(): XMLHttpRequest { return (this.mock = new MockXMLHttpRequest()) as any; }
} }
@ -30,8 +31,10 @@ export class MockXMLHttpRequestUpload {
export class MockXMLHttpRequest { export class MockXMLHttpRequest {
// Set by method calls. // Set by method calls.
body: any; body: any;
method: string; // TODO(issue/24571): remove '!'.
url: string; method !: string;
// TODO(issue/24571): remove '!'.
url !: string;
mockHeaders: {[key: string]: string} = {}; mockHeaders: {[key: string]: string} = {};
mockAborted: boolean = false; mockAborted: boolean = false;

View File

@ -38,10 +38,13 @@ import {Directive, DoCheck, ElementRef, Input, IterableChanges, IterableDiffer,
*/ */
@Directive({selector: '[ngClass]'}) @Directive({selector: '[ngClass]'})
export class NgClass implements DoCheck { export class NgClass implements DoCheck {
private _iterableDiffer: IterableDiffer<string>|null; // TODO(issue/24571): remove '!'.
private _keyValueDiffer: KeyValueDiffer<string, any>|null; private _iterableDiffer !: IterableDiffer<string>| null;
// TODO(issue/24571): remove '!'.
private _keyValueDiffer !: KeyValueDiffer<string, any>| null;
private _initialClasses: string[] = []; private _initialClasses: string[] = [];
private _rawClass: string[]|Set<string>|{[klass: string]: any}; // TODO(issue/24571): remove '!'.
private _rawClass !: string[] | Set<string>| {[klass: string]: any};
constructor( constructor(
private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers, private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers,

View File

@ -66,10 +66,14 @@ import {ComponentFactoryResolver, ComponentRef, Directive, Injector, Input, NgMo
*/ */
@Directive({selector: '[ngComponentOutlet]'}) @Directive({selector: '[ngComponentOutlet]'})
export class NgComponentOutlet implements OnChanges, OnDestroy { export class NgComponentOutlet implements OnChanges, OnDestroy {
@Input() ngComponentOutlet: Type<any>; // TODO(issue/24571): remove '!'.
@Input() ngComponentOutletInjector: Injector; @Input() ngComponentOutlet !: Type<any>;
@Input() ngComponentOutletContent: any[][]; // TODO(issue/24571): remove '!'.
@Input() ngComponentOutletNgModuleFactory: NgModuleFactory<any>; @Input() ngComponentOutletInjector !: Injector;
// TODO(issue/24571): remove '!'.
@Input() ngComponentOutletContent !: any[][];
// TODO(issue/24571): remove '!'.
@Input() ngComponentOutletNgModuleFactory !: NgModuleFactory<any>;
private _componentRef: ComponentRef<any>|null = null; private _componentRef: ComponentRef<any>|null = null;
private _moduleRef: NgModuleRef<any>|null = null; private _moduleRef: NgModuleRef<any>|null = null;

View File

@ -114,10 +114,12 @@ export class NgForOf<T> implements DoCheck {
get ngForTrackBy(): TrackByFunction<T> { return this._trackByFn; } get ngForTrackBy(): TrackByFunction<T> { return this._trackByFn; }
private _ngForOf: NgIterable<T>; // TODO(issue/24571): remove '!'.
private _ngForOf !: NgIterable<T>;
private _ngForOfDirty: boolean = true; private _ngForOfDirty: boolean = true;
private _differ: IterableDiffer<T>|null = null; private _differ: IterableDiffer<T>|null = null;
private _trackByFn: TrackByFunction<T>; // TODO(issue/24571): remove '!'.
private _trackByFn !: TrackByFunction<T>;
constructor( constructor(
private _viewContainer: ViewContainerRef, private _template: TemplateRef<NgForOfContext<T>>, private _viewContainer: ViewContainerRef, private _template: TemplateRef<NgForOfContext<T>>,

View File

@ -46,8 +46,10 @@ import {SwitchView} from './ng_switch';
*/ */
@Directive({selector: '[ngPlural]'}) @Directive({selector: '[ngPlural]'})
export class NgPlural { export class NgPlural {
private _switchValue: number; // TODO(issue/24571): remove '!'.
private _activeView: SwitchView; private _switchValue !: number;
// TODO(issue/24571): remove '!'.
private _activeView !: SwitchView;
private _caseViews: {[k: string]: SwitchView} = {}; private _caseViews: {[k: string]: SwitchView} = {};
constructor(private _localization: NgLocalization) {} constructor(private _localization: NgLocalization) {}

View File

@ -32,8 +32,10 @@ import {Directive, DoCheck, ElementRef, Input, KeyValueChanges, KeyValueDiffer,
*/ */
@Directive({selector: '[ngStyle]'}) @Directive({selector: '[ngStyle]'})
export class NgStyle implements DoCheck { export class NgStyle implements DoCheck {
private _ngStyle: {[key: string]: string}; // TODO(issue/24571): remove '!'.
private _differ: KeyValueDiffer<string, string|number>; private _ngStyle !: {[key: string]: string};
// TODO(issue/24571): remove '!'.
private _differ !: KeyValueDiffer<string, string|number>;
constructor( constructor(
private _differs: KeyValueDiffers, private _ngEl: ElementRef, private _renderer: Renderer2) {} private _differs: KeyValueDiffers, private _ngEl: ElementRef, private _renderer: Renderer2) {}

View File

@ -75,7 +75,8 @@ export class SwitchView {
*/ */
@Directive({selector: '[ngSwitch]'}) @Directive({selector: '[ngSwitch]'})
export class NgSwitch { export class NgSwitch {
private _defaultViews: SwitchView[]; // TODO(issue/24571): remove '!'.
private _defaultViews !: SwitchView[];
private _defaultUsed = false; private _defaultUsed = false;
private _caseCount = 0; private _caseCount = 0;
private _lastCaseCheckIndex = 0; private _lastCaseCheckIndex = 0;

View File

@ -34,11 +34,14 @@ import {Directive, EmbeddedViewRef, Input, OnChanges, SimpleChange, SimpleChange
*/ */
@Directive({selector: '[ngTemplateOutlet]'}) @Directive({selector: '[ngTemplateOutlet]'})
export class NgTemplateOutlet implements OnChanges { export class NgTemplateOutlet implements OnChanges {
private _viewRef: EmbeddedViewRef<any>; // TODO(issue/24571): remove '!'.
private _viewRef !: EmbeddedViewRef<any>;
@Input() public ngTemplateOutletContext: Object; // TODO(issue/24571): remove '!'.
@Input() public ngTemplateOutletContext !: Object;
@Input() public ngTemplateOutlet: TemplateRef<any>; // TODO(issue/24571): remove '!'.
@Input() public ngTemplateOutlet !: TemplateRef<any>;
constructor(private _viewContainerRef: ViewContainerRef) {} constructor(private _viewContainerRef: ViewContainerRef) {}

View File

@ -42,8 +42,10 @@ export interface KeyValue<K, V> {
export class KeyValuePipe implements PipeTransform { export class KeyValuePipe implements PipeTransform {
constructor(private readonly differs: KeyValueDiffers) {} constructor(private readonly differs: KeyValueDiffers) {}
private differ: KeyValueDiffer<any, any>; // TODO(issue/24571): remove '!'.
private keyValues: Array<KeyValue<any, any>>; private differ !: KeyValueDiffer<any, any>;
// TODO(issue/24571): remove '!'.
private keyValues !: Array<KeyValue<any, any>>;
transform<K, V>(input: null, compareFn?: (a: KeyValue<K, V>, b: KeyValue<K, V>) => number): null; transform<K, V>(input: null, compareFn?: (a: KeyValue<K, V>, b: KeyValue<K, V>) => number): null;
transform<V>( transform<V>(

View File

@ -358,7 +358,8 @@ import {ComponentFixture, TestBed, async} from '@angular/core/testing';
@Component({selector: 'test-cmp', template: ''}) @Component({selector: 'test-cmp', template: ''})
class TestComponent { class TestComponent {
condition: boolean = true; condition: boolean = true;
items: any[]; // TODO(issue/24571): remove '!'.
items !: any[];
arrExpr: string[] = ['foo']; arrExpr: string[] = ['foo'];
setExpr: Set<string> = new Set<string>(); setExpr: Set<string> = new Set<string>();
objExpr: {[klass: string]: any}|null = {'foo': true, 'bar': false}; objExpr: {[klass: string]: any}|null = {'foo': true, 'bar': false};

View File

@ -224,16 +224,22 @@ const TEST_CMP_TEMPLATE =
`<ng-template *ngComponentOutlet="currentComponent; injector: injector; content: projectables; ngModuleFactory: module;"></ng-template>`; `<ng-template *ngComponentOutlet="currentComponent; injector: injector; content: projectables; ngModuleFactory: module;"></ng-template>`;
@Component({selector: 'test-cmp', template: TEST_CMP_TEMPLATE}) @Component({selector: 'test-cmp', template: TEST_CMP_TEMPLATE})
class TestComponent { class TestComponent {
currentComponent: Type<any>|null; // TODO(issue/24571): remove '!'.
injector: Injector; currentComponent !: Type<any>| null;
projectables: any[][]; // TODO(issue/24571): remove '!'.
module: NgModuleFactory<any>; injector !: Injector;
// TODO(issue/24571): remove '!'.
projectables !: any[][];
// TODO(issue/24571): remove '!'.
module !: NgModuleFactory<any>;
get cmpRef(): ComponentRef<any>|null { return this.ngComponentOutlet['_componentRef']; } get cmpRef(): ComponentRef<any>|null { return this.ngComponentOutlet['_componentRef']; }
set cmpRef(value: ComponentRef<any>|null) { this.ngComponentOutlet['_componentRef'] = value; } set cmpRef(value: ComponentRef<any>|null) { this.ngComponentOutlet['_componentRef'] = value; }
@ViewChildren(TemplateRef) tplRefs: QueryList<TemplateRef<any>>; // TODO(issue/24571): remove '!'.
@ViewChild(NgComponentOutlet) ngComponentOutlet: NgComponentOutlet; @ViewChildren(TemplateRef) tplRefs !: QueryList<TemplateRef<any>>;
// TODO(issue/24571): remove '!'.
@ViewChild(NgComponentOutlet) ngComponentOutlet !: NgComponentOutlet;
constructor(public vcRef: ViewContainerRef) {} constructor(public vcRef: ViewContainerRef) {}
} }

View File

@ -224,12 +224,14 @@ class DestroyableCmpt implements OnDestroy {
@Directive({selector: 'tpl-refs', exportAs: 'tplRefs'}) @Directive({selector: 'tpl-refs', exportAs: 'tplRefs'})
class CaptureTplRefs { class CaptureTplRefs {
@ContentChildren(TemplateRef) tplRefs: QueryList<TemplateRef<any>>; // TODO(issue/24571): remove '!'.
@ContentChildren(TemplateRef) tplRefs !: QueryList<TemplateRef<any>>;
} }
@Component({selector: 'test-cmp', template: ''}) @Component({selector: 'test-cmp', template: ''})
class TestComponent { class TestComponent {
currentTplRef: TemplateRef<any>; // TODO(issue/24571): remove '!'.
currentTplRef !: TemplateRef<any>;
context: any = {foo: 'bar'}; context: any = {foo: 'bar'};
value = 'bar'; value = 'bar';
} }

View File

@ -14,6 +14,7 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"noImplicitAny": true, "noImplicitAny": true,
"strictNullChecks": true, "strictNullChecks": true,
"strictPropertyInitialization": true,
"skipLibCheck": true, "skipLibCheck": true,
"moduleResolution": "node", "moduleResolution": "node",
"rootDir": "", "rootDir": "",

View File

@ -13,6 +13,7 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"noImplicitAny": true, "noImplicitAny": true,
"strictNullChecks": true, "strictNullChecks": true,
"strictPropertyInitialization": true,
"skipLibCheck": true, "skipLibCheck": true,
"moduleResolution": "node", "moduleResolution": "node",
"rootDir": "", "rootDir": "",

View File

@ -185,7 +185,8 @@ export function getExpressionScope(
class ExpressionDiagnosticsVisitor extends RecursiveTemplateAstVisitor { class ExpressionDiagnosticsVisitor extends RecursiveTemplateAstVisitor {
private path: TemplateAstPath; private path: TemplateAstPath;
private directiveSummary: CompileDirectiveSummary; // TODO(issue/24571): remove '!'.
private directiveSummary !: CompileDirectiveSummary;
diagnostics: ExpressionDiagnostic[] = []; diagnostics: ExpressionDiagnostic[] = [];

View File

@ -23,7 +23,8 @@ export class TypeDiagnostic {
// AstType calculatetype of the ast given AST element. // AstType calculatetype of the ast given AST element.
export class AstType implements AstVisitor { export class AstType implements AstVisitor {
public diagnostics: TypeDiagnostic[]; // TODO(issue/24571): remove '!'.
public diagnostics !: TypeDiagnostic[];
constructor( constructor(
private scope: SymbolTable, private query: SymbolQuery, private scope: SymbolTable, private query: SymbolQuery,
@ -334,7 +335,8 @@ export class AstType implements AstVisitor {
return this.resolvePropertyRead(this.query.getNonNullableType(this.getType(ast.receiver)), ast); return this.resolvePropertyRead(this.query.getNonNullableType(this.getType(ast.receiver)), ast);
} }
private _anyType: Symbol; // TODO(issue/24571): remove '!'.
private _anyType !: Symbol;
private get anyType(): Symbol { private get anyType(): Symbol {
let result = this._anyType; let result = this._anyType;
if (!result) { if (!result) {
@ -343,7 +345,8 @@ export class AstType implements AstVisitor {
return result; return result;
} }
private _undefinedType: Symbol; // TODO(issue/24571): remove '!'.
private _undefinedType !: Symbol;
private get undefinedType(): Symbol { private get undefinedType(): Symbol {
let result = this._undefinedType; let result = this._undefinedType;
if (!result) { if (!result) {

View File

@ -84,7 +84,8 @@ export function getPipesTable(
class TypeScriptSymbolQuery implements SymbolQuery { class TypeScriptSymbolQuery implements SymbolQuery {
private typeCache = new Map<BuiltinType, Symbol>(); private typeCache = new Map<BuiltinType, Symbol>();
private pipesCache: SymbolTable; // TODO(issue/24571): remove '!'.
private pipesCache !: SymbolTable;
constructor( constructor(
private program: ts.Program, private checker: ts.TypeChecker, private source: ts.SourceFile, private program: ts.Program, private checker: ts.TypeChecker, private source: ts.SourceFile,
@ -283,8 +284,10 @@ class TypeWrapper implements Symbol {
class SymbolWrapper implements Symbol { class SymbolWrapper implements Symbol {
private symbol: ts.Symbol; private symbol: ts.Symbol;
private _tsType: ts.Type; // TODO(issue/24571): remove '!'.
private _members: SymbolTable; private _tsType !: ts.Type;
// TODO(issue/24571): remove '!'.
private _members !: SymbolTable;
public readonly nullable: boolean = false; public readonly nullable: boolean = false;
public readonly language: string = 'typescript'; public readonly language: string = 'typescript';
@ -529,7 +532,8 @@ class PipesTable implements SymbolTable {
const INDEX_PATTERN = /[\\/]([^\\/]+)[\\/]\1\.d\.ts$/; const INDEX_PATTERN = /[\\/]([^\\/]+)[\\/]\1\.d\.ts$/;
class PipeSymbol implements Symbol { class PipeSymbol implements Symbol {
private _tsType: ts.Type; // TODO(issue/24571): remove '!'.
private _tsType !: ts.Type;
public readonly kind: DeclarationKind = 'pipe'; public readonly kind: DeclarationKind = 'pipe';
public readonly language: string = 'typescript'; public readonly language: string = 'typescript';
public readonly container: Symbol|undefined = undefined; public readonly container: Symbol|undefined = undefined;

View File

@ -85,7 +85,8 @@ export class MetadataBundler {
private exports = new Map<string, Symbol[]>(); private exports = new Map<string, Symbol[]>();
private rootModule: string; private rootModule: string;
private privateSymbolPrefix: string; private privateSymbolPrefix: string;
private exported: Set<Symbol>; // TODO(issue/24571): remove '!'.
private exported !: Set<Symbol>;
constructor( constructor(
private root: string, private importAs: string|undefined, private host: MetadataBundlerHost, private root: string, private importAs: string|undefined, private host: MetadataBundlerHost,

View File

@ -11,7 +11,8 @@ import * as ts from 'typescript';
import {MetadataSymbolicReferenceExpression, MetadataValue} from './schema'; import {MetadataSymbolicReferenceExpression, MetadataValue} from './schema';
export class Symbols { export class Symbols {
private _symbols: Map<string, MetadataValue>; // TODO(issue/24571): remove '!'.
private _symbols !: Map<string, MetadataValue>;
private references = new Map<string, MetadataSymbolicReferenceExpression>(); private references = new Map<string, MetadataSymbolicReferenceExpression>();
constructor(private sourceFile: ts.SourceFile) {} constructor(private sourceFile: ts.SourceFile) {}

View File

@ -88,7 +88,8 @@ export abstract class Reference {
/** /**
* Whether an `Expression` can be generated which references the node. * Whether an `Expression` can be generated which references the node.
*/ */
readonly expressable: boolean; // TODO(issue/24571): remove '!'.
readonly expressable !: boolean;
/** /**
* Generate an `Expression` representing this type, in the context of the given SourceFile. * Generate an `Expression` representing this type, in the context of the given SourceFile.

View File

@ -120,7 +120,7 @@ export class IvyCompilation {
// Look up the .d.ts transformer for the input file and record that a field was generated, // Look up the .d.ts transformer for the input file and record that a field was generated,
// which will allow the .d.ts to be transformed later. // which will allow the .d.ts to be transformed later.
const fileName = node.getSourceFile().fileName; const fileName = original.getSourceFile().fileName;
const dtsTransformer = this.getDtsTransformer(fileName); const dtsTransformer = this.getDtsTransformer(fileName);
dtsTransformer.recordStaticField(reflectNameOfDeclaration(node) !, res); dtsTransformer.recordStaticField(reflectNameOfDeclaration(node) !, res);

View File

@ -74,10 +74,14 @@ export class TsCompilerAotCompilerTypeCheckHostAdapter implements ts.CompilerHos
private emitter = new TypeScriptEmitter(); private emitter = new TypeScriptEmitter();
private metadataReaderHost: MetadataReaderHost; private metadataReaderHost: MetadataReaderHost;
getCancellationToken: () => ts.CancellationToken; // TODO(issue/24571): remove '!'.
getDefaultLibLocation: () => string; getCancellationToken !: () => ts.CancellationToken;
trace: (s: string) => void; // TODO(issue/24571): remove '!'.
getDirectories: (path: string) => string[]; getDefaultLibLocation !: () => string;
// TODO(issue/24571): remove '!'.
trace !: (s: string) => void;
// TODO(issue/24571): remove '!'.
getDirectories !: (path: string) => string[];
directoryExists?: (directoryName: string) => boolean; directoryExists?: (directoryName: string) => boolean;
constructor( constructor(

View File

@ -252,7 +252,8 @@ function isLiteralFieldNamed(node: ts.Node, names: Set<string>): boolean {
} }
export class LowerMetadataTransform implements RequestsMap, MetadataTransformer { export class LowerMetadataTransform implements RequestsMap, MetadataTransformer {
private cache: MetadataCache; // TODO(issue/24571): remove '!'.
private cache !: MetadataCache;
private requests = new Map<string, RequestLocationMap>(); private requests = new Map<string, RequestLocationMap>();
private lowerableFieldNames: Set<string>; private lowerableFieldNames: Set<string>;

View File

@ -115,7 +115,8 @@ class AngularCompilerProgram implements Program {
private rootNames: string[]; private rootNames: string[];
private metadataCache: MetadataCache; private metadataCache: MetadataCache;
// Metadata cache used exclusively for the flat module index // Metadata cache used exclusively for the flat module index
private flatModuleMetadataCache: MetadataCache; // TODO(issue/24571): remove '!'.
private flatModuleMetadataCache !: MetadataCache;
private loweringMetadataTransform: LowerMetadataTransform; private loweringMetadataTransform: LowerMetadataTransform;
private oldProgramLibrarySummaries: Map<string, LibrarySummary>|undefined; private oldProgramLibrarySummaries: Map<string, LibrarySummary>|undefined;
private oldProgramEmittedGeneratedFiles: Map<string, GeneratedFile>|undefined; private oldProgramEmittedGeneratedFiles: Map<string, GeneratedFile>|undefined;
@ -127,15 +128,19 @@ class AngularCompilerProgram implements Program {
private emittedSourceFiles: ts.SourceFile[]|undefined; private emittedSourceFiles: ts.SourceFile[]|undefined;
// Lazily initialized fields // Lazily initialized fields
private _compiler: AotCompiler; // TODO(issue/24571): remove '!'.
private _hostAdapter: TsCompilerAotCompilerTypeCheckHostAdapter; private _compiler !: AotCompiler;
private _tsProgram: ts.Program; // TODO(issue/24571): remove '!'.
private _hostAdapter !: TsCompilerAotCompilerTypeCheckHostAdapter;
// TODO(issue/24571): remove '!'.
private _tsProgram !: ts.Program;
private _analyzedModules: NgAnalyzedModules|undefined; private _analyzedModules: NgAnalyzedModules|undefined;
private _analyzedInjectables: NgAnalyzedFileWithInjectables[]|undefined; private _analyzedInjectables: NgAnalyzedFileWithInjectables[]|undefined;
private _structuralDiagnostics: Diagnostic[]|undefined; private _structuralDiagnostics: Diagnostic[]|undefined;
private _programWithStubs: ts.Program|undefined; private _programWithStubs: ts.Program|undefined;
private _optionsDiagnostics: Diagnostic[] = []; private _optionsDiagnostics: Diagnostic[] = [];
private _reifiedDecorators: Set<StaticSymbol>; // TODO(issue/24571): remove '!'.
private _reifiedDecorators !: Set<StaticSymbol>;
constructor( constructor(
rootNames: ReadonlyArray<string>, private options: CompilerOptions, rootNames: ReadonlyArray<string>, private options: CompilerOptions,

View File

@ -117,12 +117,14 @@ const summaryResolver = new AotSummaryResolver(
export class DiagnosticContext { export class DiagnosticContext {
// tslint:disable // tslint:disable
_analyzedModules: NgAnalyzedModules; // TODO(issue/24571): remove '!'.
_analyzedModules !: NgAnalyzedModules;
_staticSymbolResolver: StaticSymbolResolver|undefined; _staticSymbolResolver: StaticSymbolResolver|undefined;
_reflector: StaticReflector|undefined; _reflector: StaticReflector|undefined;
_errors: {e: any, path?: string}[] = []; _errors: {e: any, path?: string}[] = [];
_resolver: CompileMetadataResolver|undefined; _resolver: CompileMetadataResolver|undefined;
_refletor: StaticReflector; // TODO(issue/24571): remove '!'.
_refletor !: StaticReflector;
// tslint:enable // tslint:enable
constructor( constructor(

View File

@ -102,7 +102,8 @@ export class MockNode implements ts.Node {
export class MockIdentifier extends MockNode implements ts.Identifier { export class MockIdentifier extends MockNode implements ts.Identifier {
public text: string; public text: string;
public escapedText: ts.__String; // TODO(issue/24571): remove '!'.
public escapedText !: ts.__String;
// tslint:disable // tslint:disable
public _declarationBrand: any; public _declarationBrand: any;
public _primaryExpressionBrand: any; public _primaryExpressionBrand: any;
@ -139,7 +140,8 @@ export class MockVariableDeclaration extends MockNode implements ts.VariableDecl
} }
export class MockSymbol implements ts.Symbol { export class MockSymbol implements ts.Symbol {
public escapedName: ts.__String; // TODO(issue/24571): remove '!'.
public escapedName !: ts.__String;
constructor( constructor(
public name: string, private node: ts.Declaration = MockVariableDeclaration.of(name), public name: string, private node: ts.Declaration = MockVariableDeclaration.of(name),
public flags: ts.SymbolFlags = 0) {} public flags: ts.SymbolFlags = 0) {}

View File

@ -49,10 +49,14 @@ export class StaticReflector implements CompileReflector {
private staticCache = new Map<StaticSymbol, string[]>(); private staticCache = new Map<StaticSymbol, string[]>();
private conversionMap = new Map<StaticSymbol, (context: StaticSymbol, args: any[]) => any>(); private conversionMap = new Map<StaticSymbol, (context: StaticSymbol, args: any[]) => any>();
private resolvedExternalReferences = new Map<string, StaticSymbol>(); private resolvedExternalReferences = new Map<string, StaticSymbol>();
private injectionToken: StaticSymbol; // TODO(issue/24571): remove '!'.
private opaqueToken: StaticSymbol; private injectionToken !: StaticSymbol;
ROUTES: StaticSymbol; // TODO(issue/24571): remove '!'.
private ANALYZE_FOR_ENTRY_COMPONENTS: StaticSymbol; private opaqueToken !: StaticSymbol;
// TODO(issue/24571): remove '!'.
ROUTES !: StaticSymbol;
// TODO(issue/24571): remove '!'.
private ANALYZE_FOR_ENTRY_COMPONENTS !: StaticSymbol;
private annotationForParentClassWithSummaryKind = private annotationForParentClassWithSummaryKind =
new Map<CompileSummaryKind, MetadataFactory<any>[]>(); new Map<CompileSummaryKind, MetadataFactory<any>[]>();

View File

@ -421,7 +421,8 @@ class ForJitSerializer {
} }
class FromJsonDeserializer extends ValueTransformer { class FromJsonDeserializer extends ValueTransformer {
private symbols: StaticSymbol[]; // TODO(issue/24571): remove '!'.
private symbols !: StaticSymbol[];
constructor( constructor(
private symbolCache: StaticSymbolCache, private symbolCache: StaticSymbolCache,

View File

@ -528,7 +528,8 @@ export interface CompileNgModuleSummary extends CompileTypeSummary {
} }
export class CompileShallowModuleMetadata { export class CompileShallowModuleMetadata {
type: CompileTypeMetadata; // TODO(issue/24571): remove '!'.
type !: CompileTypeMetadata;
rawExports: any; rawExports: any;
rawImports: any; rawImports: any;

View File

@ -40,7 +40,8 @@ const KEY_CONTEXT = {};
class FixupExpression extends o.Expression { class FixupExpression extends o.Expression {
private original: o.Expression; private original: o.Expression;
shared: boolean; // TODO(issue/24571): remove '!'.
shared !: boolean;
constructor(public resolved: o.Expression) { constructor(public resolved: o.Expression) {
super(resolved.type); super(resolved.type);

View File

@ -116,7 +116,8 @@ function _trackWhitespace(mode: CssLexerMode) {
} }
export class CssScanner { export class CssScanner {
peek: number; // TODO(issue/24571): remove '!'.
peek !: number;
peekPeek: number; peekPeek: number;
length: number = 0; length: number = 0;
index: number = -1; index: number = -1;

View File

@ -83,9 +83,12 @@ export class ParsedCssResult {
export class CssParser { export class CssParser {
private _errors: CssParseError[] = []; private _errors: CssParseError[] = [];
private _file: ParseSourceFile; // TODO(issue/24571): remove '!'.
private _scanner: CssScanner; private _file !: ParseSourceFile;
private _lastToken: CssToken; // TODO(issue/24571): remove '!'.
private _scanner !: CssScanner;
// TODO(issue/24571): remove '!'.
private _lastToken !: CssToken;
/** /**
* @param css the CSS code that will be parsed * @param css the CSS code that will be parsed

View File

@ -55,33 +55,46 @@ enum _VisitorMode {
* @internal * @internal
*/ */
class _Visitor implements html.Visitor { class _Visitor implements html.Visitor {
private _depth: number; // TODO(issue/24571): remove '!'.
private _depth !: number;
// <el i18n>...</el> // <el i18n>...</el>
private _inI18nNode: boolean; // TODO(issue/24571): remove '!'.
private _inImplicitNode: boolean; private _inI18nNode !: boolean;
// TODO(issue/24571): remove '!'.
private _inImplicitNode !: boolean;
// <!--i18n-->...<!--/i18n--> // <!--i18n-->...<!--/i18n-->
private _inI18nBlock: boolean; // TODO(issue/24571): remove '!'.
private _blockMeaningAndDesc: string; private _inI18nBlock !: boolean;
private _blockChildren: html.Node[]; // TODO(issue/24571): remove '!'.
private _blockStartDepth: number; private _blockMeaningAndDesc !: string;
// TODO(issue/24571): remove '!'.
private _blockChildren !: html.Node[];
// TODO(issue/24571): remove '!'.
private _blockStartDepth !: number;
// {<icu message>} // {<icu message>}
private _inIcu: boolean; // TODO(issue/24571): remove '!'.
private _inIcu !: boolean;
// set to void 0 when not in a section // set to void 0 when not in a section
private _msgCountAtSectionStart: number|undefined; private _msgCountAtSectionStart: number|undefined;
private _errors: I18nError[]; // TODO(issue/24571): remove '!'.
private _mode: _VisitorMode; private _errors !: I18nError[];
// TODO(issue/24571): remove '!'.
private _mode !: _VisitorMode;
// _VisitorMode.Extract only // _VisitorMode.Extract only
private _messages: i18n.Message[]; // TODO(issue/24571): remove '!'.
private _messages !: i18n.Message[];
// _VisitorMode.Merge only // _VisitorMode.Merge only
private _translations: TranslationBundle; // TODO(issue/24571): remove '!'.
private _createI18nMessage: private _translations !: TranslationBundle;
(msg: html.Node[], meaning: string, description: string, id: string) => i18n.Message; // TODO(issue/24571): remove '!'.
private _createI18nMessage !: (
msg: html.Node[], meaning: string, description: string, id: string) => i18n.Message;
constructor(private _implicitTags: string[], private _implicitAttrs: {[k: string]: string[]}) {} constructor(private _implicitTags: string[], private _implicitAttrs: {[k: string]: string[]}) {}

View File

@ -65,7 +65,8 @@ export class Container implements Node {
} }
export class Icu implements Node { export class Icu implements Node {
public expressionPlaceholder: string; // TODO(issue/24571): remove '!'.
public expressionPlaceholder !: string;
constructor( constructor(
public expression: string, public type: string, public cases: {[k: string]: Node}, public expression: string, public type: string, public cases: {[k: string]: Node},
public sourceSpan: ParseSourceSpan) {} public sourceSpan: ParseSourceSpan) {}

View File

@ -30,11 +30,16 @@ export function createI18nMessageFactory(interpolationConfig: InterpolationConfi
} }
class _I18nVisitor implements html.Visitor { class _I18nVisitor implements html.Visitor {
private _isIcu: boolean; // TODO(issue/24571): remove '!'.
private _icuDepth: number; private _isIcu !: boolean;
private _placeholderRegistry: PlaceholderRegistry; // TODO(issue/24571): remove '!'.
private _placeholderToContent: {[phName: string]: string}; private _icuDepth !: number;
private _placeholderToMessage: {[phName: string]: i18n.Message}; // TODO(issue/24571): remove '!'.
private _placeholderRegistry !: PlaceholderRegistry;
// TODO(issue/24571): remove '!'.
private _placeholderToContent !: {[phName: string]: string};
// TODO(issue/24571): remove '!'.
private _placeholderToMessage !: {[phName: string]: i18n.Message};
constructor( constructor(
private _expressionParser: ExpressionParser, private _expressionParser: ExpressionParser,

View File

@ -173,9 +173,12 @@ class _WriteVisitor implements i18n.Visitor {
// TODO(vicb): add error management (structure) // TODO(vicb): add error management (structure)
// Extract messages as xml nodes from the xliff file // Extract messages as xml nodes from the xliff file
class XliffParser implements ml.Visitor { class XliffParser implements ml.Visitor {
private _unitMlString: string|null; // TODO(issue/24571): remove '!'.
private _errors: I18nError[]; private _unitMlString !: string | null;
private _msgIdToHtml: {[msgId: string]: string}; // TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
// TODO(issue/24571): remove '!'.
private _msgIdToHtml !: {[msgId: string]: string};
private _locale: string|null = null; private _locale: string|null = null;
parse(xliff: string, url: string) { parse(xliff: string, url: string) {
@ -261,7 +264,8 @@ class XliffParser implements ml.Visitor {
// Convert ml nodes (xliff syntax) to i18n nodes // Convert ml nodes (xliff syntax) to i18n nodes
class XmlToI18n implements ml.Visitor { class XmlToI18n implements ml.Visitor {
private _errors: I18nError[]; // TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
convert(message: string, url: string) { convert(message: string, url: string) {
const xmlIcu = new XmlParser().parse(message, url, true); const xmlIcu = new XmlParser().parse(message, url, true);

View File

@ -112,7 +112,8 @@ export class Xliff2 extends Serializer {
} }
class _WriteVisitor implements i18n.Visitor { class _WriteVisitor implements i18n.Visitor {
private _nextPlaceholderId: number; // TODO(issue/24571): remove '!'.
private _nextPlaceholderId !: number;
visitText(text: i18n.Text, context?: any): xml.Node[] { return [new xml.Text(text.value)]; } visitText(text: i18n.Text, context?: any): xml.Node[] { return [new xml.Text(text.value)]; }
@ -190,9 +191,12 @@ class _WriteVisitor implements i18n.Visitor {
// Extract messages as xml nodes from the xliff file // Extract messages as xml nodes from the xliff file
class Xliff2Parser implements ml.Visitor { class Xliff2Parser implements ml.Visitor {
private _unitMlString: string|null; // TODO(issue/24571): remove '!'.
private _errors: I18nError[]; private _unitMlString !: string | null;
private _msgIdToHtml: {[msgId: string]: string}; // TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
// TODO(issue/24571): remove '!'.
private _msgIdToHtml !: {[msgId: string]: string};
private _locale: string|null = null; private _locale: string|null = null;
parse(xliff: string, url: string) { parse(xliff: string, url: string) {
@ -285,7 +289,8 @@ class Xliff2Parser implements ml.Visitor {
// Convert ml nodes (xliff syntax) to i18n nodes // Convert ml nodes (xliff syntax) to i18n nodes
class XmlToI18n implements ml.Visitor { class XmlToI18n implements ml.Visitor {
private _errors: I18nError[]; // TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
convert(message: string, url: string) { convert(message: string, url: string) {
const xmlIcu = new XmlParser().parse(message, url, true); const xmlIcu = new XmlParser().parse(message, url, true);

View File

@ -74,9 +74,12 @@ function createLazyProperty(messages: any, id: string, valueFn: () => any) {
// Extract messages as xml nodes from the xtb file // Extract messages as xml nodes from the xtb file
class XtbParser implements ml.Visitor { class XtbParser implements ml.Visitor {
private _bundleDepth: number; // TODO(issue/24571): remove '!'.
private _errors: I18nError[]; private _bundleDepth !: number;
private _msgIdToHtml: {[msgId: string]: string}; // TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
// TODO(issue/24571): remove '!'.
private _msgIdToHtml !: {[msgId: string]: string};
private _locale: string|null = null; private _locale: string|null = null;
parse(xtb: string, url: string) { parse(xtb: string, url: string) {
@ -152,7 +155,8 @@ class XtbParser implements ml.Visitor {
// Convert ml nodes (xtb syntax) to i18n nodes // Convert ml nodes (xtb syntax) to i18n nodes
class XmlToI18n implements ml.Visitor { class XmlToI18n implements ml.Visitor {
private _errors: I18nError[]; // TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
convert(message: string, url: string) { convert(message: string, url: string) {
const xmlIcu = new XmlParser().parse(message, url, true); const xmlIcu = new XmlParser().parse(message, url, true);

View File

@ -60,10 +60,12 @@ export class TranslationBundle {
} }
class I18nToHtmlVisitor implements i18n.Visitor { class I18nToHtmlVisitor implements i18n.Visitor {
private _srcMsg: i18n.Message; // TODO(issue/24571): remove '!'.
private _srcMsg !: i18n.Message;
private _contextStack: {msg: i18n.Message, mapper: (name: string) => string}[] = []; private _contextStack: {msg: i18n.Message, mapper: (name: string) => string}[] = [];
private _errors: I18nError[] = []; private _errors: I18nError[] = [];
private _mapper: (name: string) => string; // TODO(issue/24571): remove '!'.
private _mapper !: (name: string) => string;
constructor( constructor(
private _i18nNodesByMsgId: {[msgId: string]: i18n.Node[]} = {}, private _locale: string|null, private _i18nNodesByMsgId: {[msgId: string]: i18n.Node[]} = {}, private _locale: string|null,

View File

@ -12,8 +12,10 @@ export class HtmlTagDefinition implements TagDefinition {
private closedByChildren: {[key: string]: boolean} = {}; private closedByChildren: {[key: string]: boolean} = {};
closedByParent: boolean = false; closedByParent: boolean = false;
requiredParents: {[key: string]: boolean}; // TODO(issue/24571): remove '!'.
parentToAdd: string; requiredParents !: {[key: string]: boolean};
// TODO(issue/24571): remove '!'.
parentToAdd !: string;
implicitNamespacePrefix: string|null; implicitNamespacePrefix: string|null;
contentType: TagContentType; contentType: TagContentType;
isVoid: boolean; isVoid: boolean;

View File

@ -84,8 +84,10 @@ class _Tokenizer {
private _index: number = -1; private _index: number = -1;
private _line: number = 0; private _line: number = 0;
private _column: number = -1; private _column: number = -1;
private _currentTokenStart: ParseLocation; // TODO(issue/24571): remove '!'.
private _currentTokenType: TokenType; private _currentTokenStart !: ParseLocation;
// TODO(issue/24571): remove '!'.
private _currentTokenType !: TokenType;
private _expansionCaseStack: TokenType[] = []; private _expansionCaseStack: TokenType[] = [];
private _inInterpolation: boolean = false; private _inInterpolation: boolean = false;

View File

@ -46,7 +46,8 @@ export class Parser {
class _TreeBuilder { class _TreeBuilder {
private _index: number = -1; private _index: number = -1;
private _peek: lex.Token; // TODO(issue/24571): remove '!'.
private _peek !: lex.Token;
private _rootNodes: html.Node[] = []; private _rootNodes: html.Node[] = [];
private _errors: TreeError[] = []; private _errors: TreeError[] = [];

View File

@ -10,9 +10,12 @@ import {TagContentType, TagDefinition} from './tags';
export class XmlTagDefinition implements TagDefinition { export class XmlTagDefinition implements TagDefinition {
closedByParent: boolean = false; closedByParent: boolean = false;
requiredParents: {[key: string]: boolean}; // TODO(issue/24571): remove '!'.
parentToAdd: string; requiredParents !: {[key: string]: boolean};
implicitNamespacePrefix: string; // TODO(issue/24571): remove '!'.
parentToAdd !: string;
// TODO(issue/24571): remove '!'.
implicitNamespacePrefix !: string;
contentType: TagContentType = TagContentType.PARSABLE_DATA; contentType: TagContentType = TagContentType.PARSABLE_DATA;
isVoid: boolean = false; isVoid: boolean = false;
ignoreFirstLf: boolean = false; ignoreFirstLf: boolean = false;

View File

@ -11,8 +11,10 @@ import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../../../src/ml
class Unparser implements AstVisitor { class Unparser implements AstVisitor {
private static _quoteRegExp = /"/g; private static _quoteRegExp = /"/g;
private _expression: string; // TODO(issue/24571): remove '!'.
private _interpolationConfig: InterpolationConfig; private _expression !: string;
// TODO(issue/24571): remove '!'.
private _interpolationConfig !: InterpolationConfig;
unparse(ast: AST, interpolationConfig: InterpolationConfig) { unparse(ast: AST, interpolationConfig: InterpolationConfig) {
this._expression = ''; this._expression = '';

View File

@ -19,9 +19,12 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
template: '', template: '',
}) })
export class I18nComponent { export class I18nComponent {
count: number; // TODO(issue/24571): remove '!'.
sex: string; count !: number;
sexB: string; // TODO(issue/24571): remove '!'.
sex !: string;
// TODO(issue/24571): remove '!'.
sexB !: string;
response: any = {getItemsList: (): any[] => []}; response: any = {getItemsList: (): any[] => []};
} }

View File

@ -20,7 +20,8 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
it('should support dotted selectors', async(() => { it('should support dotted selectors', async(() => {
@Directive({selector: '[dot.name]'}) @Directive({selector: '[dot.name]'})
class MyDir { class MyDir {
@Input('dot.name') value: string; // TODO(issue/24571): remove '!'.
@Input('dot.name') value !: string;
} }
TestBed.configureTestingModule({ TestBed.configureTestingModule({

View File

@ -99,8 +99,10 @@ export class MockResourceLoader extends ResourceLoader {
} }
class _PendingRequest { class _PendingRequest {
resolve: (result: string) => void; // TODO(issue/24571): remove '!'.
reject: (error: any) => void; resolve !: (result: string) => void;
// TODO(issue/24571): remove '!'.
reject !: (error: any) => void;
promise: Promise<string>; promise: Promise<string>;
constructor(public url: string) { constructor(public url: string) {

View File

@ -7,6 +7,7 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"noImplicitAny": true, "noImplicitAny": true,
"strictNullChecks": true, "strictNullChecks": true,
"strictPropertyInitialization": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"module": "es2015", "module": "es2015",
"moduleResolution": "node", "moduleResolution": "node",

View File

@ -24,8 +24,10 @@ export const APP_INITIALIZER = new InjectionToken<Array<() => void>>('Applicatio
*/ */
@Injectable() @Injectable()
export class ApplicationInitStatus { export class ApplicationInitStatus {
private resolve: Function; // TODO(issue/24571): remove '!'.
private reject: Function; private resolve !: Function;
// TODO(issue/24571): remove '!'.
private reject !: Function;
private initialized = false; private initialized = false;
public readonly donePromise: Promise<any>; public readonly donePromise: Promise<any>;
public readonly done = false; public readonly done = false;

View File

@ -383,7 +383,8 @@ export class ApplicationRef {
/** /**
* Returns an Observable that indicates when the application is stable or unstable. * Returns an Observable that indicates when the application is stable or unstable.
*/ */
public readonly isStable: Observable<boolean>; // TODO(issue/24571): remove '!'.
public readonly isStable !: Observable<boolean>;
/** @internal */ /** @internal */
constructor( constructor(

View File

@ -27,7 +27,8 @@ const trackByIdentity = (index: number, item: any) => item;
*/ */
export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChanges<V> { export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChanges<V> {
public readonly length: number = 0; public readonly length: number = 0;
public readonly collection: V[]|Iterable<V>|null; // TODO(issue/24571): remove '!'.
public readonly collection !: V[] | Iterable<V>| null;
// Keeps track of the used records at any point in time (during & across `_check()` calls) // Keeps track of the used records at any point in time (during & across `_check()` calls)
private _linkedRecords: _DuplicateMap<V>|null = null; private _linkedRecords: _DuplicateMap<V>|null = null;
// Keeps track of the removed records at any point in time during `_check()` calls. // Keeps track of the removed records at any point in time during `_check()` calls.

View File

@ -19,7 +19,8 @@ export class EventListener {
export class DebugNode { export class DebugNode {
nativeNode: any; nativeNode: any;
listeners: EventListener[]; listeners: EventListener[];
parent: DebugElement|null; // TODO(issue/24571): remove '!'.
parent !: DebugElement | null;
constructor(nativeNode: any, parent: DebugNode|null, private _debugContext: DebugContext) { constructor(nativeNode: any, parent: DebugNode|null, private _debugContext: DebugContext) {
this.nativeNode = nativeNode; this.nativeNode = nativeNode;
@ -46,7 +47,8 @@ export class DebugNode {
* @experimental All debugging apis are currently experimental. * @experimental All debugging apis are currently experimental.
*/ */
export class DebugElement extends DebugNode { export class DebugElement extends DebugNode {
name: string; // TODO(issue/24571): remove '!'.
name !: string;
properties: {[key: string]: any}; properties: {[key: string]: any};
attributes: {[key: string]: string | null}; attributes: {[key: string]: string | null};
classes: {[key: string]: boolean}; classes: {[key: string]: boolean};

View File

@ -42,8 +42,10 @@ export class QueryList<T>/* implements Iterable<T> */ {
public readonly changes: Observable<any> = new EventEmitter(); public readonly changes: Observable<any> = new EventEmitter();
readonly length: number = 0; readonly length: number = 0;
readonly first: T; // TODO(issue/24571): remove '!'.
readonly last: T; readonly first !: T;
// TODO(issue/24571): remove '!'.
readonly last !: T;
/** /**
* See * See

View File

@ -28,12 +28,14 @@ export abstract class SystemJsNgModuleLoaderConfig {
/** /**
* Prefix to add when computing the name of the factory module for a given module name. * Prefix to add when computing the name of the factory module for a given module name.
*/ */
factoryPathPrefix: string; // TODO(issue/24571): remove '!'.
factoryPathPrefix !: string;
/** /**
* Suffix to add when computing the name of the factory module for a given module name. * Suffix to add when computing the name of the factory module for a given module name.
*/ */
factoryPathSuffix: string; // TODO(issue/24571): remove '!'.
factoryPathSuffix !: string;
} }
const DEFAULT_CONFIG: SystemJsNgModuleLoaderConfig = { const DEFAULT_CONFIG: SystemJsNgModuleLoaderConfig = {

View File

@ -159,7 +159,8 @@ export abstract class Renderer2 {
* in which case the view engine won't call it. * in which case the view engine won't call it.
* This is used as a performance optimization for production mode. * This is used as a performance optimization for production mode.
*/ */
destroyNode: ((node: any) => void)|null; // TODO(issue/24571): remove '!'.
destroyNode !: ((node: any) => void) | null;
abstract appendChild(parent: any, newChild: any): void; abstract appendChild(parent: any, newChild: any): void;
abstract insertBefore(parent: any, newChild: any, refChild: any): void; abstract insertBefore(parent: any, newChild: any, refChild: any): void;
abstract removeChild(parent: any, oldChild: any): void; abstract removeChild(parent: any, oldChild: any): void;

View File

@ -606,9 +606,12 @@ export function getOrCreateContainerRef(di: LInjector): viewEngine_ViewContainer
*/ */
class ViewContainerRef implements viewEngine_ViewContainerRef { class ViewContainerRef implements viewEngine_ViewContainerRef {
private _viewRefs: viewEngine_ViewRef[] = []; private _viewRefs: viewEngine_ViewRef[] = [];
element: viewEngine_ElementRef; // TODO(issue/24571): remove '!'.
injector: Injector; element !: viewEngine_ElementRef;
parentInjector: Injector; // TODO(issue/24571): remove '!'.
injector !: Injector;
// TODO(issue/24571): remove '!'.
parentInjector !: Injector;
constructor(private _lContainerNode: LContainerNode) {} constructor(private _lContainerNode: LContainerNode) {}

View File

@ -24,10 +24,12 @@ export interface viewEngine_ChangeDetectorRef_interface extends viewEngine_Chang
export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_InternalViewRef, export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_InternalViewRef,
viewEngine_ChangeDetectorRef_interface { viewEngine_ChangeDetectorRef_interface {
private _appRef: ApplicationRef|null; // TODO(issue/24571): remove '!'.
private _appRef !: ApplicationRef | null;
context: T; context: T;
rootNodes: any[]; // TODO(issue/24571): remove '!'.
rootNodes !: any[];
constructor(protected _view: LViewData, context: T|null) { this.context = context !; } constructor(protected _view: LViewData, context: T|null) { this.context = context !; }

View File

@ -311,7 +311,8 @@ class TemplateRef_ extends TemplateRef<any> implements TemplateData {
/** /**
* @internal * @internal
*/ */
_projectedViews: ViewData[]; // TODO(issue/24571): remove '!'.
_projectedViews !: ViewData[];
constructor(private _parentView: ViewData, private _def: NodeDef) { super(); } constructor(private _parentView: ViewData, private _def: NodeDef) { super(); }
@ -479,9 +480,11 @@ class NgModuleRef_ implements NgModuleData, InternalNgModuleRef<any> {
private _destroyListeners: (() => void)[] = []; private _destroyListeners: (() => void)[] = [];
private _destroyed: boolean = false; private _destroyed: boolean = false;
/** @internal */ /** @internal */
_providers: any[]; // TODO(issue/24571): remove '!'.
_providers !: any[];
/** @internal */ /** @internal */
_modules: any[]; // TODO(issue/24571): remove '!'.
_modules !: any[];
readonly injector: Injector = this; readonly injector: Injector = this;

View File

@ -1636,7 +1636,8 @@ const DEFAULT_COMPONENT_ID = '1';
] ]
}) })
class Cmp { class Cmp {
public exp: string|null; // TODO(issue/24571): remove '!'.
public exp !: string | null;
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -2023,7 +2024,8 @@ const DEFAULT_COMPONENT_ID = '1';
}) })
class Cmp { class Cmp {
public exp: any; public exp: any;
public color: string|null; // TODO(issue/24571): remove '!'.
public color !: string | null;
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -2456,7 +2458,8 @@ const DEFAULT_COMPONENT_ID = '1';
}) })
class Cmp { class Cmp {
exp: any = false; exp: any = false;
event: AnimationEvent; // TODO(issue/24571): remove '!'.
event !: AnimationEvent;
callback = (event: any) => { this.event = event; }; callback = (event: any) => { this.event = event; };
} }
@ -2491,7 +2494,8 @@ const DEFAULT_COMPONENT_ID = '1';
}) })
class Cmp { class Cmp {
exp: any = false; exp: any = false;
event: AnimationEvent; // TODO(issue/24571): remove '!'.
event !: AnimationEvent;
callback = (event: any) => { this.event = event; }; callback = (event: any) => { this.event = event; };
} }
@ -2546,8 +2550,10 @@ const DEFAULT_COMPONENT_ID = '1';
class Cmp { class Cmp {
exp1: any = false; exp1: any = false;
exp2: any = false; exp2: any = false;
event1: AnimationEvent; // TODO(issue/24571): remove '!'.
event2: AnimationEvent; event1 !: AnimationEvent;
// TODO(issue/24571): remove '!'.
event2 !: AnimationEvent;
// tslint:disable:semicolon // tslint:disable:semicolon
callback1 = (event: any) => { this.event1 = event; }; callback1 = (event: any) => { this.event1 = event; };
// tslint:disable:semicolon // tslint:disable:semicolon
@ -2608,8 +2614,10 @@ const DEFAULT_COMPONENT_ID = '1';
class Cmp { class Cmp {
exp1: any = false; exp1: any = false;
exp2: any = false; exp2: any = false;
event1: AnimationEvent; // TODO(issue/24571): remove '!'.
event2: AnimationEvent; event1 !: AnimationEvent;
// TODO(issue/24571): remove '!'.
event2 !: AnimationEvent;
callback1 = (event: any) => { this.event1 = event; }; callback1 = (event: any) => { this.event1 = event; };
callback2 = (event: any) => { this.event2 = event; }; callback2 = (event: any) => { this.event2 = event; };
} }
@ -2713,7 +2721,8 @@ const DEFAULT_COMPONENT_ID = '1';
[style({'opacity': '0'}), animate(1000, style({'opacity': '1'}))])])], [style({'opacity': '0'}), animate(1000, style({'opacity': '1'}))])])],
}) })
class Cmp { class Cmp {
event: AnimationEvent; // TODO(issue/24571): remove '!'.
event !: AnimationEvent;
@HostBinding('@myAnimation2') @HostBinding('@myAnimation2')
exp: any = false; exp: any = false;
@ -2747,7 +2756,8 @@ const DEFAULT_COMPONENT_ID = '1';
animations: [trigger('myAnimation', [])] animations: [trigger('myAnimation', [])]
}) })
class Cmp { class Cmp {
exp: string; // TODO(issue/24571): remove '!'.
exp !: string;
log: any[] = []; log: any[] = [];
callback = (event: any) => this.log.push(`${event.phaseName} => ${event.toState}`); callback = (event: any) => this.log.push(`${event.phaseName} => ${event.toState}`);
} }
@ -2858,8 +2868,10 @@ const DEFAULT_COMPONENT_ID = '1';
}) })
class Cmp { class Cmp {
log: string[] = []; log: string[] = [];
exp1: string; // TODO(issue/24571): remove '!'.
exp2: string; exp1 !: string;
// TODO(issue/24571): remove '!'.
exp2 !: string;
cb(name: string, event: AnimationEvent) { this.log.push(name); } cb(name: string, event: AnimationEvent) { this.log.push(name); }
} }
@ -2936,7 +2948,8 @@ const DEFAULT_COMPONENT_ID = '1';
class Cmp { class Cmp {
log: string[] = []; log: string[] = [];
events: {[name: string]: any} = {}; events: {[name: string]: any} = {};
exp: string; // TODO(issue/24571): remove '!'.
exp !: string;
items: any = [0, 1, 2, 3]; items: any = [0, 1, 2, 3];
cb(name: string, phase: string, event: AnimationEvent) { cb(name: string, phase: string, event: AnimationEvent) {
@ -3263,8 +3276,10 @@ const DEFAULT_COMPONENT_ID = '1';
class Cmp { class Cmp {
disableExp = false; disableExp = false;
exp = ''; exp = '';
startEvent: AnimationEvent; // TODO(issue/24571): remove '!'.
doneEvent: AnimationEvent; startEvent !: AnimationEvent;
// TODO(issue/24571): remove '!'.
doneEvent !: AnimationEvent;
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});

View File

@ -1049,7 +1049,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
])] ])]
}) })
class Cmp { class Cmp {
public items: any[]; // TODO(issue/24571): remove '!'.
public items !: any[];
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -1129,7 +1130,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
}) })
class Cmp { class Cmp {
public exp: any; public exp: any;
public items: any[]; // TODO(issue/24571): remove '!'.
public items !: any[];
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -1349,7 +1351,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
}) })
class Cmp { class Cmp {
public exp: any; public exp: any;
public items: any[]; // TODO(issue/24571): remove '!'.
public items !: any[];
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -1401,7 +1404,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
}) })
class Cmp { class Cmp {
public exp: any; public exp: any;
public items: any[]; // TODO(issue/24571): remove '!'.
public items !: any[];
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -1463,7 +1467,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
class Cmp { class Cmp {
public exp1: any; public exp1: any;
public exp2: any; public exp2: any;
public items: any[]; // TODO(issue/24571): remove '!'.
public items !: any[];
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -1532,7 +1537,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
}) })
class Cmp { class Cmp {
public exp: any; public exp: any;
public items: any[]; // TODO(issue/24571): remove '!'.
public items !: any[];
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -1586,7 +1592,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
}) })
class Cmp { class Cmp {
public exp: any; public exp: any;
public items: any[]; // TODO(issue/24571): remove '!'.
public items !: any[];
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -2469,7 +2476,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
` `
}) })
class Cmp { class Cmp {
public exp: boolean; // TODO(issue/24571): remove '!'.
public exp !: boolean;
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -2648,7 +2656,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
` `
}) })
class Cmp { class Cmp {
public exp: boolean; // TODO(issue/24571): remove '!'.
public exp !: boolean;
public log: string[] = []; public log: string[] = [];
callback(event: any) { callback(event: any) {
this.log.push(event.element.getAttribute('data-name') + '-' + event.phaseName); this.log.push(event.element.getAttribute('data-name') + '-' + event.phaseName);

View File

@ -138,7 +138,8 @@ import {TestBed} from '../../testing';
[transition('* => *', [style({height: '!'}), animate(1000, style({height: '*'}))])])] [transition('* => *', [style({height: '!'}), animate(1000, style({height: '*'}))])])]
}) })
class Cmp { class Cmp {
public exp: number; // TODO(issue/24571): remove '!'.
public exp !: number;
public items = [0, 1, 2, 3, 4]; public items = [0, 1, 2, 3, 4];
} }
@ -358,7 +359,8 @@ import {TestBed} from '../../testing';
] ]
}) })
class Cmp { class Cmp {
public exp: string; // TODO(issue/24571): remove '!'.
public exp !: string;
} }
TestBed.configureTestingModule({declarations: [Cmp]}); TestBed.configureTestingModule({declarations: [Cmp]});
@ -411,7 +413,8 @@ import {TestBed} from '../../testing';
] ]
}) })
class Cmp { class Cmp {
public exp: string; // TODO(issue/24571): remove '!'.
public exp !: string;
public items: any[] = []; public items: any[] = [];
} }

View File

@ -356,14 +356,16 @@ class SomeComponent {
@Component({template: '<ng-container #vc></ng-container>'}) @Component({template: '<ng-container #vc></ng-container>'})
class ContainerComp { class ContainerComp {
// TODO(issue/24571): remove '!'.
@ViewChild('vc', {read: ViewContainerRef}) @ViewChild('vc', {read: ViewContainerRef})
vc: ViewContainerRef; vc !: ViewContainerRef;
} }
@Component({template: '<ng-template #t>Dynamic content</ng-template>'}) @Component({template: '<ng-template #t>Dynamic content</ng-template>'})
class EmbeddedViewComp { class EmbeddedViewComp {
// TODO(issue/24571): remove '!'.
@ViewChild(TemplateRef) @ViewChild(TemplateRef)
tplRef: TemplateRef<Object>; tplRef !: TemplateRef<Object>;
} }
beforeEach(() => { beforeEach(() => {

View File

@ -14,7 +14,8 @@ import {Component, Injectable, IterableDiffers, NgModule, defineInjector, ɵNgOn
export class Todo { export class Todo {
editing: boolean; editing: boolean;
private _title: string; // TODO(issue/24571): remove '!'.
private _title !: string;
get title() { return this._title; } get title() { return this._title; }
set title(value: string) { this._title = value.trim(); } set title(value: string) { this._title = value.trim(); }

View File

@ -141,10 +141,13 @@ class LocalsComp {
` `
}) })
class BankAccount { class BankAccount {
@Input() bank: string; // TODO(issue/24571): remove '!'.
@Input('account') id: string; @Input() bank !: string;
// TODO(issue/24571): remove '!'.
@Input('account') id !: string;
normalizedBankName: string; // TODO(issue/24571): remove '!'.
normalizedBankName !: string;
} }
@Component({ @Component({

View File

@ -46,7 +46,8 @@ class App {
template: `{{frame.name}}(<span *ngFor="let lock of locks">{{lock.name}}</span>)`, template: `{{frame.name}}(<span *ngFor="let lock of locks">{{lock.name}}</span>)`,
}) })
class Door { class Door {
@ContentChildren(forwardRef(() => Lock)) locks: QueryList<Lock>; // TODO(issue/24571): remove '!'.
@ContentChildren(forwardRef(() => Lock)) locks !: QueryList<Lock>;
frame: Frame; frame: Frame;
constructor(@Inject(forwardRef(() => Frame)) frame: Frame) { this.frame = frame; } constructor(@Inject(forwardRef(() => Frame)) frame: Frame) { this.frame = frame; }

View File

@ -1310,8 +1310,10 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
@Component({template: '<ng-template #vc>{{name}}</ng-template>'}) @Component({template: '<ng-template #vc>{{name}}</ng-template>'})
class Comp { class Comp {
name = 'Tom'; name = 'Tom';
@ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef; // TODO(issue/24571): remove '!'.
@ViewChild(TemplateRef) template: TemplateRef<any>; @ViewChild('vc', {read: ViewContainerRef}) vc !: ViewContainerRef;
// TODO(issue/24571): remove '!'.
@ViewChild(TemplateRef) template !: TemplateRef<any>;
} }
TestBed.configureTestingModule({declarations: [Comp]}); TestBed.configureTestingModule({declarations: [Comp]});
@ -1351,8 +1353,9 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
`<span [i]="log('start')"></span><inner-cmp [outerTpl]="tpl"><ng-template><span [i]="log('tpl')"></span></ng-template></inner-cmp>` `<span [i]="log('start')"></span><inner-cmp [outerTpl]="tpl"><ng-template><span [i]="log('tpl')"></span></ng-template></inner-cmp>`
}) })
class OuterComp { class OuterComp {
// TODO(issue/24571): remove '!'.
@ContentChild(TemplateRef) @ContentChild(TemplateRef)
tpl: TemplateRef<any>; tpl !: TemplateRef<any>;
constructor(public cdRef: ChangeDetectorRef) {} constructor(public cdRef: ChangeDetectorRef) {}
log(id: string) { log.push(`outer-${id}`); } log(id: string) { log.push(`outer-${id}`); }
@ -1364,11 +1367,13 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
`<span [i]="log('start')"></span>><ng-container [ngTemplateOutlet]="outerTpl"></ng-container><ng-container [ngTemplateOutlet]="tpl"></ng-container>` `<span [i]="log('start')"></span>><ng-container [ngTemplateOutlet]="outerTpl"></ng-container><ng-container [ngTemplateOutlet]="tpl"></ng-container>`
}) })
class InnerComp { class InnerComp {
// TODO(issue/24571): remove '!'.
@ContentChild(TemplateRef) @ContentChild(TemplateRef)
tpl: TemplateRef<any>; tpl !: TemplateRef<any>;
// TODO(issue/24571): remove '!'.
@Input() @Input()
outerTpl: TemplateRef<any>; outerTpl !: TemplateRef<any>;
constructor(public cdRef: ChangeDetectorRef) {} constructor(public cdRef: ChangeDetectorRef) {}
log(id: string) { log.push(`inner-${id}`); } log(id: string) { log.push(`inner-${id}`); }
@ -1517,7 +1522,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
class MyChild { class MyChild {
private thrown = LifetimeMethods.None; private thrown = LifetimeMethods.None;
@Input() inp: boolean; // TODO(issue/24571): remove '!'.
@Input() inp !: boolean;
@Output() outp = new EventEmitter<any>(); @Output() outp = new EventEmitter<any>();
constructor() {} constructor() {}
@ -1793,13 +1799,16 @@ class TestDirective implements OnInit, DoCheck, OnChanges, AfterContentInit, Aft
AfterViewInit, AfterViewChecked, OnDestroy { AfterViewInit, AfterViewChecked, OnDestroy {
@Input() a: any; @Input() a: any;
@Input() b: any; @Input() b: any;
changes: SimpleChanges; // TODO(issue/24571): remove '!'.
changes !: SimpleChanges;
event: any; event: any;
eventEmitter: EventEmitter<string> = new EventEmitter<string>(); eventEmitter: EventEmitter<string> = new EventEmitter<string>();
@Input('testDirective') name: string; // TODO(issue/24571): remove '!'.
@Input('testDirective') name !: string;
@Input() throwOn: string; // TODO(issue/24571): remove '!'.
@Input() throwOn !: string;
constructor(public log: DirectiveLog) {} constructor(public log: DirectiveLog) {}
@ -1875,7 +1884,8 @@ class OnDestroyDirective implements OnDestroy {
@Directive({selector: '[orderCheck0]'}) @Directive({selector: '[orderCheck0]'})
class OrderCheckDirective0 { class OrderCheckDirective0 {
private _name: string; // TODO(issue/24571): remove '!'.
private _name !: string;
@Input('orderCheck0') @Input('orderCheck0')
set name(value: string) { set name(value: string) {
@ -1888,7 +1898,8 @@ class OrderCheckDirective0 {
@Directive({selector: '[orderCheck1]'}) @Directive({selector: '[orderCheck1]'})
class OrderCheckDirective1 { class OrderCheckDirective1 {
private _name: string; // TODO(issue/24571): remove '!'.
private _name !: string;
@Input('orderCheck1') @Input('orderCheck1')
set name(value: string) { set name(value: string) {
@ -1901,7 +1912,8 @@ class OrderCheckDirective1 {
@Directive({selector: '[orderCheck2]'}) @Directive({selector: '[orderCheck2]'})
class OrderCheckDirective2 { class OrderCheckDirective2 {
private _name: string; // TODO(issue/24571): remove '!'.
private _name !: string;
@Input('orderCheck2') @Input('orderCheck2')
set name(value: string) { set name(value: string) {
@ -1925,10 +1937,13 @@ class TestLocals {
@Component({selector: 'root', template: 'empty'}) @Component({selector: 'root', template: 'empty'})
class Person { class Person {
age: number; // TODO(issue/24571): remove '!'.
name: string; age !: number;
// TODO(issue/24571): remove '!'.
name !: string;
address: Address|null = null; address: Address|null = null;
phones: number[]; // TODO(issue/24571): remove '!'.
phones !: number[];
init(name: string, address: Address|null = null) { init(name: string, address: Address|null = null) {
this.name = name; this.name = name;
@ -1982,13 +1997,15 @@ class TestData {
@Component({selector: 'root', template: 'empty'}) @Component({selector: 'root', template: 'empty'})
class TestDataWithGetter { class TestDataWithGetter {
public fn: Function; // TODO(issue/24571): remove '!'.
public fn !: Function;
get a() { return this.fn(); } get a() { return this.fn(); }
} }
class Holder<T> { class Holder<T> {
value: T; // TODO(issue/24571): remove '!'.
value !: T;
} }
@Component({selector: 'root', template: 'empty'}) @Component({selector: 'root', template: 'empty'})

View File

@ -939,7 +939,8 @@ function declareTests({useJit}: {useJit: boolean}) {
@Directive({selector: '[host-listener]', host: {'(click)': 'doIt(id, unknownProp)'}}) @Directive({selector: '[host-listener]', host: {'(click)': 'doIt(id, unknownProp)'}})
class DirectiveWithHostListener { class DirectiveWithHostListener {
id = 'one'; id = 'one';
receivedArgs: any[]; // TODO(issue/24571): remove '!'.
receivedArgs !: any[];
doIt(...args: any[]) { this.receivedArgs = args; } doIt(...args: any[]) { this.receivedArgs = args; }
} }
@ -1956,12 +1957,14 @@ class MyDir {
@Directive({selector: '[title]', inputs: ['title']}) @Directive({selector: '[title]', inputs: ['title']})
class DirectiveWithTitle { class DirectiveWithTitle {
title: string; // TODO(issue/24571): remove '!'.
title !: string;
} }
@Directive({selector: '[title]', inputs: ['title'], host: {'[title]': 'title'}}) @Directive({selector: '[title]', inputs: ['title'], host: {'[title]': 'title'}})
class DirectiveWithTitleAndHostProperty { class DirectiveWithTitleAndHostProperty {
title: string; // TODO(issue/24571): remove '!'.
title !: string;
} }
@Component({selector: 'event-cmp', template: '<div (click)="noop()"></div>'}) @Component({selector: 'event-cmp', template: '<div (click)="noop()"></div>'})
@ -2032,7 +2035,8 @@ class PushCmpWithHostEvent {
}) })
class PushCmpWithAsyncPipe { class PushCmpWithAsyncPipe {
numberOfChecks: number = 0; numberOfChecks: number = 0;
resolve: (result: any) => void; // TODO(issue/24571): remove '!'.
resolve !: (result: any) => void;
promise: Promise<any>; promise: Promise<any>;
constructor() { constructor() {
@ -2218,7 +2222,8 @@ class DirectiveListeningDomEventNoPrevent {
@Directive({selector: '[id]', inputs: ['id']}) @Directive({selector: '[id]', inputs: ['id']})
class IdDir { class IdDir {
id: string; // TODO(issue/24571): remove '!'.
id !: string;
} }
@Directive({selector: '[customEvent]'}) @Directive({selector: '[customEvent]'})
@ -2281,7 +2286,8 @@ class ToolbarViewContainer {
template: 'TOOLBAR(<div *ngFor="let part of query" [toolbarVc]="part"></div>)', template: 'TOOLBAR(<div *ngFor="let part of query" [toolbarVc]="part"></div>)',
}) })
class ToolbarComponent { class ToolbarComponent {
@ContentChildren(ToolbarPart) query: QueryList<ToolbarPart>; // TODO(issue/24571): remove '!'.
@ContentChildren(ToolbarPart) query !: QueryList<ToolbarPart>;
ctxProp: string = 'hello world'; ctxProp: string = 'hello world';
constructor() {} constructor() {}
@ -2481,10 +2487,12 @@ class ComponentWithTemplate {
class DirectiveWithPropDecorators { class DirectiveWithPropDecorators {
target: any; target: any;
@Input('elProp') dirProp: string; // TODO(issue/24571): remove '!'.
@Input('elProp') dirProp !: string;
@Output('elEvent') event = new EventEmitter(); @Output('elEvent') event = new EventEmitter();
@HostBinding('attr.my-attr') myAttr: string; // TODO(issue/24571): remove '!'.
@HostBinding('attr.my-attr') myAttr !: string;
@HostListener('click', ['$event.target']) @HostListener('click', ['$event.target'])
onClick(target: any) { this.target = target; } onClick(target: any) { this.target = target; }

View File

@ -161,16 +161,20 @@ class TextDirective {
@Component({selector: 'needs-content-children', template: ''}) @Component({selector: 'needs-content-children', template: ''})
class NeedsContentChildren implements AfterContentInit { class NeedsContentChildren implements AfterContentInit {
@ContentChildren(TextDirective) textDirChildren: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
numberOfChildrenAfterContentInit: number; @ContentChildren(TextDirective) textDirChildren !: QueryList<TextDirective>;
// TODO(issue/24571): remove '!'.
numberOfChildrenAfterContentInit !: number;
ngAfterContentInit() { this.numberOfChildrenAfterContentInit = this.textDirChildren.length; } ngAfterContentInit() { this.numberOfChildrenAfterContentInit = this.textDirChildren.length; }
} }
@Component({selector: 'needs-view-children', template: '<div text></div>'}) @Component({selector: 'needs-view-children', template: '<div text></div>'})
class NeedsViewChildren implements AfterViewInit { class NeedsViewChildren implements AfterViewInit {
@ViewChildren(TextDirective) textDirChildren: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
numberOfChildrenAfterViewInit: number; @ViewChildren(TextDirective) textDirChildren !: QueryList<TextDirective>;
// TODO(issue/24571): remove '!'.
numberOfChildrenAfterViewInit !: number;
ngAfterViewInit() { this.numberOfChildrenAfterViewInit = this.textDirChildren.length; } ngAfterViewInit() { this.numberOfChildrenAfterViewInit = this.textDirChildren.length; }
} }

View File

@ -55,7 +55,8 @@ class CarWithDashboard {
@Injectable() @Injectable()
class SportsCar extends Car { class SportsCar extends Car {
engine: Engine; // TODO(issue/24571): remove '!'.
engine !: Engine;
constructor(engine: Engine) { super(engine); } constructor(engine: Engine) { super(engine); }
} }
@ -82,8 +83,9 @@ class SomeComp {
@Directive({selector: '[someDir]'}) @Directive({selector: '[someDir]'})
class SomeDirective { class SomeDirective {
// TODO(issue/24571): remove '!'.
@HostBinding('title') @Input() @HostBinding('title') @Input()
someDir: string; someDir !: string;
} }
@Pipe({name: 'somePipe'}) @Pipe({name: 'somePipe'})

View File

@ -614,11 +614,13 @@ import {stringify} from '../../src/util';
@Component( @Component(
{selector: 'auto-projecting', template: '<div *ngIf="true; then: content"></div>'}) {selector: 'auto-projecting', template: '<div *ngIf="true; then: content"></div>'})
class AutoProjecting { class AutoProjecting {
// TODO(issue/24571): remove '!'.
@ContentChild(TemplateRef) @ContentChild(TemplateRef)
content: TemplateRef<any>; content !: TemplateRef<any>;
// TODO(issue/24571): remove '!'.
@ContentChildren(TextDirective) @ContentChildren(TextDirective)
query: QueryList<TextDirective>; query !: QueryList<TextDirective>;
} }
TestBed.configureTestingModule({declarations: [AutoProjecting]}); TestBed.configureTestingModule({declarations: [AutoProjecting]});
@ -638,22 +640,27 @@ import {stringify} from '../../src/util';
@Directive({selector: '[text]', inputs: ['text'], exportAs: 'textDir'}) @Directive({selector: '[text]', inputs: ['text'], exportAs: 'textDir'})
class TextDirective { class TextDirective {
text: string; // TODO(issue/24571): remove '!'.
text !: string;
constructor() {} constructor() {}
} }
@Component({selector: 'needs-content-children', template: ''}) @Component({selector: 'needs-content-children', template: ''})
class NeedsContentChildren implements AfterContentInit { class NeedsContentChildren implements AfterContentInit {
@ContentChildren(TextDirective) textDirChildren: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
numberOfChildrenAfterContentInit: number; @ContentChildren(TextDirective) textDirChildren !: QueryList<TextDirective>;
// TODO(issue/24571): remove '!'.
numberOfChildrenAfterContentInit !: number;
ngAfterContentInit() { this.numberOfChildrenAfterContentInit = this.textDirChildren.length; } ngAfterContentInit() { this.numberOfChildrenAfterContentInit = this.textDirChildren.length; }
} }
@Component({selector: 'needs-view-children', template: '<div text></div>'}) @Component({selector: 'needs-view-children', template: '<div text></div>'})
class NeedsViewChildren implements AfterViewInit { class NeedsViewChildren implements AfterViewInit {
@ViewChildren(TextDirective) textDirChildren: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
numberOfChildrenAfterViewInit: number; @ViewChildren(TextDirective) textDirChildren !: QueryList<TextDirective>;
// TODO(issue/24571): remove '!'.
numberOfChildrenAfterViewInit !: number;
ngAfterViewInit() { this.numberOfChildrenAfterViewInit = this.textDirChildren.length; } ngAfterViewInit() { this.numberOfChildrenAfterViewInit = this.textDirChildren.length; }
} }
@ -661,7 +668,8 @@ class NeedsViewChildren implements AfterViewInit {
@Component({selector: 'needs-content-child', template: ''}) @Component({selector: 'needs-content-child', template: ''})
class NeedsContentChild implements AfterContentInit, AfterContentChecked { class NeedsContentChild implements AfterContentInit, AfterContentChecked {
/** @internal */ /** @internal */
_child: TextDirective; // TODO(issue/24571): remove '!'.
_child !: TextDirective;
@ContentChild(TextDirective) @ContentChild(TextDirective)
set child(value) { set child(value) {
@ -679,7 +687,8 @@ class NeedsContentChild implements AfterContentInit, AfterContentChecked {
@Directive({selector: '[directive-needs-content-child]'}) @Directive({selector: '[directive-needs-content-child]'})
class DirectiveNeedsContentChild { class DirectiveNeedsContentChild {
@ContentChild(TextDirective) child: TextDirective; // TODO(issue/24571): remove '!'.
@ContentChild(TextDirective) child !: TextDirective;
} }
@Component({selector: 'needs-view-child', template: `<div *ngIf="shouldShow" text="foo"></div>`}) @Component({selector: 'needs-view-child', template: `<div *ngIf="shouldShow" text="foo"></div>`})
@ -687,7 +696,8 @@ class NeedsViewChild implements AfterViewInit, AfterViewChecked {
shouldShow: boolean = true; shouldShow: boolean = true;
shouldShow2: boolean = false; shouldShow2: boolean = false;
/** @internal */ /** @internal */
_child: TextDirective; // TODO(issue/24571): remove '!'.
_child !: TextDirective;
@ViewChild(TextDirective) @ViewChild(TextDirective)
set child(value) { set child(value) {
@ -717,8 +727,10 @@ function createTestCmpAndDetectChanges<T>(type: Type<T>, template: string): Comp
@Component({selector: 'needs-static-content-view-child', template: `<div text="viewFoo"></div>`}) @Component({selector: 'needs-static-content-view-child', template: `<div text="viewFoo"></div>`})
class NeedsStaticContentAndViewChild { class NeedsStaticContentAndViewChild {
@ContentChild(TextDirective) contentChild: TextDirective; // TODO(issue/24571): remove '!'.
@ViewChild(TextDirective) viewChild: TextDirective; @ContentChild(TextDirective) contentChild !: TextDirective;
// TODO(issue/24571): remove '!'.
@ViewChild(TextDirective) viewChild !: TextDirective;
} }
@Directive({selector: '[dir]'}) @Directive({selector: '[dir]'})
@ -730,15 +742,20 @@ class InertDirective {
template: '<div text="ignoreme"></div><b *ngFor="let dir of query">{{dir.text}}|</b>' template: '<div text="ignoreme"></div><b *ngFor="let dir of query">{{dir.text}}|</b>'
}) })
class NeedsQuery { class NeedsQuery {
@ContentChildren(TextDirective) query: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ContentChildren(TextDirective) query !: QueryList<TextDirective>;
} }
@Component({selector: 'needs-four-queries', template: ''}) @Component({selector: 'needs-four-queries', template: ''})
class NeedsFourQueries { class NeedsFourQueries {
@ContentChild(TextDirective) query1: TextDirective; // TODO(issue/24571): remove '!'.
@ContentChild(TextDirective) query2: TextDirective; @ContentChild(TextDirective) query1 !: TextDirective;
@ContentChild(TextDirective) query3: TextDirective; // TODO(issue/24571): remove '!'.
@ContentChild(TextDirective) query4: TextDirective; @ContentChild(TextDirective) query2 !: TextDirective;
// TODO(issue/24571): remove '!'.
@ContentChild(TextDirective) query3 !: TextDirective;
// TODO(issue/24571): remove '!'.
@ContentChild(TextDirective) query4 !: TextDirective;
} }
@Component({ @Component({
@ -746,22 +763,26 @@ class NeedsFourQueries {
template: '<ng-content></ng-content><div *ngFor="let dir of query">{{dir.text}}|</div>' template: '<ng-content></ng-content><div *ngFor="let dir of query">{{dir.text}}|</div>'
}) })
class NeedsQueryDesc { class NeedsQueryDesc {
@ContentChildren(TextDirective, {descendants: true}) query: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ContentChildren(TextDirective, {descendants: true}) query !: QueryList<TextDirective>;
} }
@Component({selector: 'needs-query-by-ref-binding', template: '<ng-content>'}) @Component({selector: 'needs-query-by-ref-binding', template: '<ng-content>'})
class NeedsQueryByLabel { class NeedsQueryByLabel {
@ContentChildren('textLabel', {descendants: true}) query: QueryList<any>; // TODO(issue/24571): remove '!'.
@ContentChildren('textLabel', {descendants: true}) query !: QueryList<any>;
} }
@Component({selector: 'needs-view-query-by-ref-binding', template: '<div #textLabel>text</div>'}) @Component({selector: 'needs-view-query-by-ref-binding', template: '<div #textLabel>text</div>'})
class NeedsViewQueryByLabel { class NeedsViewQueryByLabel {
@ViewChildren('textLabel') query: QueryList<any>; // TODO(issue/24571): remove '!'.
@ViewChildren('textLabel') query !: QueryList<any>;
} }
@Component({selector: 'needs-query-by-ref-bindings', template: '<ng-content>'}) @Component({selector: 'needs-query-by-ref-bindings', template: '<ng-content>'})
class NeedsQueryByTwoLabels { class NeedsQueryByTwoLabels {
@ContentChildren('textLabel1,textLabel2', {descendants: true}) query: QueryList<any>; // TODO(issue/24571): remove '!'.
@ContentChildren('textLabel1,textLabel2', {descendants: true}) query !: QueryList<any>;
} }
@Component({ @Component({
@ -769,7 +790,8 @@ class NeedsQueryByTwoLabels {
template: '<div *ngFor="let dir of query">{{dir.text}}|</div><ng-content></ng-content>' template: '<div *ngFor="let dir of query">{{dir.text}}|</div><ng-content></ng-content>'
}) })
class NeedsQueryAndProject { class NeedsQueryAndProject {
@ContentChildren(TextDirective) query: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ContentChildren(TextDirective) query !: QueryList<TextDirective>;
} }
@Component({ @Component({
@ -777,13 +799,15 @@ class NeedsQueryAndProject {
template: '<div text="1"><div text="2"></div></div><div text="3"></div><div text="4"></div>' template: '<div text="1"><div text="2"></div></div><div text="3"></div><div text="4"></div>'
}) })
class NeedsViewQuery { class NeedsViewQuery {
@ViewChildren(TextDirective) query: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ViewChildren(TextDirective) query !: QueryList<TextDirective>;
} }
@Component({selector: 'needs-view-query-if', template: '<div *ngIf="show" text="1"></div>'}) @Component({selector: 'needs-view-query-if', template: '<div *ngIf="show" text="1"></div>'})
class NeedsViewQueryIf { class NeedsViewQueryIf {
show: boolean = false; show: boolean = false;
@ViewChildren(TextDirective) query: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ViewChildren(TextDirective) query !: QueryList<TextDirective>;
} }
@Component({ @Component({
@ -792,7 +816,8 @@ class NeedsViewQueryIf {
}) })
class NeedsViewQueryNestedIf { class NeedsViewQueryNestedIf {
show: boolean = true; show: boolean = true;
@ViewChildren(TextDirective) query: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ViewChildren(TextDirective) query !: QueryList<TextDirective>;
} }
@Component({ @Component({
@ -802,7 +827,8 @@ class NeedsViewQueryNestedIf {
'<div text="4"></div>' '<div text="4"></div>'
}) })
class NeedsViewQueryOrder { class NeedsViewQueryOrder {
@ViewChildren(TextDirective) query: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ViewChildren(TextDirective) query !: QueryList<TextDirective>;
list: string[] = ['2', '3']; list: string[] = ['2', '3'];
} }
@ -813,35 +839,44 @@ class NeedsViewQueryOrder {
'<div text="4"></div></div>' '<div text="4"></div></div>'
}) })
class NeedsViewQueryOrderWithParent { class NeedsViewQueryOrderWithParent {
@ViewChildren(TextDirective) query: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ViewChildren(TextDirective) query !: QueryList<TextDirective>;
list: string[] = ['2', '3']; list: string[] = ['2', '3'];
} }
@Component({selector: 'needs-tpl', template: '<ng-template><div>shadow</div></ng-template>'}) @Component({selector: 'needs-tpl', template: '<ng-template><div>shadow</div></ng-template>'})
class NeedsTpl { class NeedsTpl {
@ViewChildren(TemplateRef) viewQuery: QueryList<TemplateRef<Object>>; // TODO(issue/24571): remove '!'.
@ContentChildren(TemplateRef) query: QueryList<TemplateRef<Object>>; @ViewChildren(TemplateRef) viewQuery !: QueryList<TemplateRef<Object>>;
// TODO(issue/24571): remove '!'.
@ContentChildren(TemplateRef) query !: QueryList<TemplateRef<Object>>;
constructor(public vc: ViewContainerRef) {} constructor(public vc: ViewContainerRef) {}
} }
@Component( @Component(
{selector: 'needs-named-tpl', template: '<ng-template #tpl><div>shadow</div></ng-template>'}) {selector: 'needs-named-tpl', template: '<ng-template #tpl><div>shadow</div></ng-template>'})
class NeedsNamedTpl { class NeedsNamedTpl {
@ViewChild('tpl') viewTpl: TemplateRef<Object>; // TODO(issue/24571): remove '!'.
@ContentChild('tpl') contentTpl: TemplateRef<Object>; @ViewChild('tpl') viewTpl !: TemplateRef<Object>;
// TODO(issue/24571): remove '!'.
@ContentChild('tpl') contentTpl !: TemplateRef<Object>;
constructor(public vc: ViewContainerRef) {} constructor(public vc: ViewContainerRef) {}
} }
@Component({selector: 'needs-content-children-read', template: ''}) @Component({selector: 'needs-content-children-read', template: ''})
class NeedsContentChildrenWithRead { class NeedsContentChildrenWithRead {
@ContentChildren('q', {read: TextDirective}) textDirChildren: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ContentChildren('nonExisting', {read: TextDirective}) nonExistingVar: QueryList<TextDirective>; @ContentChildren('q', {read: TextDirective}) textDirChildren !: QueryList<TextDirective>;
// TODO(issue/24571): remove '!'.
@ContentChildren('nonExisting', {read: TextDirective}) nonExistingVar !: QueryList<TextDirective>;
} }
@Component({selector: 'needs-content-child-read', template: ''}) @Component({selector: 'needs-content-child-read', template: ''})
class NeedsContentChildWithRead { class NeedsContentChildWithRead {
@ContentChild('q', {read: TextDirective}) textDirChild: TextDirective; // TODO(issue/24571): remove '!'.
@ContentChild('nonExisting', {read: TextDirective}) nonExistingVar: TextDirective; @ContentChild('q', {read: TextDirective}) textDirChild !: TextDirective;
// TODO(issue/24571): remove '!'.
@ContentChild('nonExisting', {read: TextDirective}) nonExistingVar !: TextDirective;
} }
@Component({ @Component({
@ -849,7 +884,8 @@ class NeedsContentChildWithRead {
template: '<div [ngTemplateOutlet]="templateRef"></div>' template: '<div [ngTemplateOutlet]="templateRef"></div>'
}) })
class NeedsContentChildTemplateRef { class NeedsContentChildTemplateRef {
@ContentChild(TemplateRef) templateRef: TemplateRef<any>; // TODO(issue/24571): remove '!'.
@ContentChild(TemplateRef) templateRef !: TemplateRef<any>;
} }
@Component({ @Component({
@ -866,8 +902,10 @@ class NeedsContentChildTemplateRefApp {
template: '<div #q text="va"></div><div #w text="vb"></div>', template: '<div #q text="va"></div><div #w text="vb"></div>',
}) })
class NeedsViewChildrenWithRead { class NeedsViewChildrenWithRead {
@ViewChildren('q,w', {read: TextDirective}) textDirChildren: QueryList<TextDirective>; // TODO(issue/24571): remove '!'.
@ViewChildren('nonExisting', {read: TextDirective}) nonExistingVar: QueryList<TextDirective>; @ViewChildren('q,w', {read: TextDirective}) textDirChildren !: QueryList<TextDirective>;
// TODO(issue/24571): remove '!'.
@ViewChildren('nonExisting', {read: TextDirective}) nonExistingVar !: QueryList<TextDirective>;
} }
@Component({ @Component({
@ -875,15 +913,20 @@ class NeedsViewChildrenWithRead {
template: '<div #q text="va"></div>', template: '<div #q text="va"></div>',
}) })
class NeedsViewChildWithRead { class NeedsViewChildWithRead {
@ViewChild('q', {read: TextDirective}) textDirChild: TextDirective; // TODO(issue/24571): remove '!'.
@ViewChild('nonExisting', {read: TextDirective}) nonExistingVar: TextDirective; @ViewChild('q', {read: TextDirective}) textDirChild !: TextDirective;
// TODO(issue/24571): remove '!'.
@ViewChild('nonExisting', {read: TextDirective}) nonExistingVar !: TextDirective;
} }
@Component({selector: 'needs-viewcontainer-read', template: '<div #q></div>'}) @Component({selector: 'needs-viewcontainer-read', template: '<div #q></div>'})
class NeedsViewContainerWithRead { class NeedsViewContainerWithRead {
@ViewChild('q', {read: ViewContainerRef}) vc: ViewContainerRef; // TODO(issue/24571): remove '!'.
@ViewChild('nonExisting', {read: ViewContainerRef}) nonExistingVar: ViewContainerRef; @ViewChild('q', {read: ViewContainerRef}) vc !: ViewContainerRef;
@ContentChild(TemplateRef) template: TemplateRef<Object>; // TODO(issue/24571): remove '!'.
@ViewChild('nonExisting', {read: ViewContainerRef}) nonExistingVar !: ViewContainerRef;
// TODO(issue/24571): remove '!'.
@ContentChild(TemplateRef) template !: TemplateRef<Object>;
createView() { this.vc.createEmbeddedView(this.template); } createView() { this.vc.createEmbeddedView(this.template); }
} }
@ -905,13 +948,16 @@ class MyCompBroken0 {
@Component({selector: 'manual-projecting', template: '<div #vc></div>'}) @Component({selector: 'manual-projecting', template: '<div #vc></div>'})
class ManualProjecting { class ManualProjecting {
@ContentChild(TemplateRef) template: TemplateRef<any>; // TODO(issue/24571): remove '!'.
@ContentChild(TemplateRef) template !: TemplateRef<any>;
// TODO(issue/24571): remove '!'.
@ViewChild('vc', {read: ViewContainerRef}) @ViewChild('vc', {read: ViewContainerRef})
vc: ViewContainerRef; vc !: ViewContainerRef;
// TODO(issue/24571): remove '!'.
@ContentChildren(TextDirective) @ContentChildren(TextDirective)
query: QueryList<TextDirective>; query !: QueryList<TextDirective>;
create() { this.vc.createEmbeddedView(this.template); } create() { this.vc.createEmbeddedView(this.template); }

View File

@ -81,7 +81,8 @@ function declareTests({useJit}: {useJit: boolean}) {
@Directive({selector: '[myDir]'}) @Directive({selector: '[myDir]'})
class MyDir { class MyDir {
setterCalls: {[key: string]: any} = {}; setterCalls: {[key: string]: any} = {};
changes: SimpleChanges; // TODO(issue/24571): remove '!'.
changes !: SimpleChanges;
@Input() @Input()
set a(v: number) { this.setterCalls['a'] = v; } set a(v: number) { this.setterCalls['a'] = v; }
@ -124,7 +125,8 @@ function declareTests({useJit}: {useJit: boolean}) {
it('should evaluate a conditional in a statement binding', () => { it('should evaluate a conditional in a statement binding', () => {
@Component({selector: 'some-comp', template: '<p (click)="nullValue?.click()"></p>'}) @Component({selector: 'some-comp', template: '<p (click)="nullValue?.click()"></p>'})
class SomeComponent { class SomeComponent {
nullValue: SomeReferencedClass; // TODO(issue/24571): remove '!'.
nullValue !: SomeReferencedClass;
} }
class SomeReferencedClass { class SomeReferencedClass {
@ -272,7 +274,8 @@ function declareTests({useJit}: {useJit: boolean}) {
@Directive({selector: '[someDir]'}) @Directive({selector: '[someDir]'})
class MyDir { class MyDir {
@Input('someDir') template: TemplateRef<any>; // TODO(issue/24571): remove '!'.
@Input('someDir') template !: TemplateRef<any>;
} }
const ctx = const ctx =
@ -292,8 +295,9 @@ function declareTests({useJit}: {useJit: boolean}) {
it('should not recreate ViewContainerRefs in queries', () => { it('should not recreate ViewContainerRefs in queries', () => {
@Component({template: '<div #vc></div><div *ngIf="show" #vc></div>'}) @Component({template: '<div #vc></div><div *ngIf="show" #vc></div>'})
class MyComp { class MyComp {
// TODO(issue/24571): remove '!'.
@ViewChildren('vc', {read: ViewContainerRef}) @ViewChildren('vc', {read: ViewContainerRef})
viewContainers: QueryList<ViewContainerRef>; viewContainers !: QueryList<ViewContainerRef>;
show = true; show = true;
} }
@ -344,7 +348,8 @@ function declareTests({useJit}: {useJit: boolean}) {
it('should support @ContentChild and @Input on the same property for static queries', () => { it('should support @ContentChild and @Input on the same property for static queries', () => {
@Directive({selector: 'test'}) @Directive({selector: 'test'})
class Test { class Test {
@Input() @ContentChild(TemplateRef) tpl: TemplateRef<any>; // TODO(issue/24571): remove '!'.
@Input() @ContentChild(TemplateRef) tpl !: TemplateRef<any>;
} }
@Component({ @Component({

View File

@ -168,8 +168,9 @@ function declareTests({useJit}: {useJit: boolean}) {
it('should escape unsafe properties if they are used in host bindings', () => { it('should escape unsafe properties if they are used in host bindings', () => {
@Directive({selector: '[dirHref]'}) @Directive({selector: '[dirHref]'})
class HrefDirective { class HrefDirective {
// TODO(issue/24571): remove '!'.
@HostBinding('href') @Input() @HostBinding('href') @Input()
dirHref: string; dirHref !: string;
} }
const template = `<a [dirHref]="ctxProp">Link Title</a>`; const template = `<a [dirHref]="ctxProp">Link Title</a>`;
@ -183,8 +184,9 @@ function declareTests({useJit}: {useJit: boolean}) {
it('should escape unsafe attributes if they are used in host bindings', () => { it('should escape unsafe attributes if they are used in host bindings', () => {
@Directive({selector: '[dirHref]'}) @Directive({selector: '[dirHref]'})
class HrefDirective { class HrefDirective {
// TODO(issue/24571): remove '!'.
@HostBinding('attr.href') @Input() @HostBinding('attr.href') @Input()
dirHref: string; dirHref !: string;
} }
const template = `<a [dirHref]="ctxProp">Link Title</a>`; const template = `<a [dirHref]="ctxProp">Link Title</a>`;

View File

@ -76,26 +76,31 @@ import {TestBed} from '@angular/core/testing';
@Directive({selector: 'simple'}) @Directive({selector: 'simple'})
class Simple { class Simple {
@Input() marker: string; // TODO(issue/24571): remove '!'.
@Input() marker !: string;
} }
@Component({selector: 'view-child-type-selector', template: ''}) @Component({selector: 'view-child-type-selector', template: ''})
class ViewChildTypeSelectorComponent { class ViewChildTypeSelectorComponent {
@ViewChild(Simple) child: Simple; // TODO(issue/24571): remove '!'.
@ViewChild(Simple) child !: Simple;
} }
@Component({selector: 'view-child-string-selector', template: ''}) @Component({selector: 'view-child-string-selector', template: ''})
class ViewChildStringSelectorComponent { class ViewChildStringSelectorComponent {
@ViewChild('child') child: ElementRef; // TODO(issue/24571): remove '!'.
@ViewChild('child') child !: ElementRef;
} }
@Component({selector: 'view-children-type-selector', template: ''}) @Component({selector: 'view-children-type-selector', template: ''})
class ViewChildrenTypeSelectorComponent { class ViewChildrenTypeSelectorComponent {
@ViewChildren(Simple) children: QueryList<Simple>; // TODO(issue/24571): remove '!'.
@ViewChildren(Simple) children !: QueryList<Simple>;
} }
@Component({selector: 'view-child-string-selector', template: ''}) @Component({selector: 'view-child-string-selector', template: ''})
class ViewChildrenStringSelectorComponent { class ViewChildrenStringSelectorComponent {
// Allow comma separated selector (with spaces). // Allow comma separated selector (with spaces).
@ViewChildren('child1 , child2') children: QueryList<ElementRef>; // TODO(issue/24571): remove '!'.
@ViewChildren('child1 , child2') children !: QueryList<ElementRef>;
} }

View File

@ -329,17 +329,21 @@ class TestObj {
class C {} class C {}
class Parent { class Parent {
// TODO(issue/24571): remove '!'.
@PropDecorator('a') @PropDecorator('a')
a: A; a !: A;
// TODO(issue/24571): remove '!'.
@PropDecorator('b1') @PropDecorator('b1')
b: B; b !: B;
} }
class Child extends Parent { class Child extends Parent {
// TODO(issue/24571): remove '!'.
@PropDecorator('b2') @PropDecorator('b2')
b: B; b !: B;
// TODO(issue/24571): remove '!'.
@PropDecorator('c') @PropDecorator('c')
c: C; c !: C;
} }
class NoDecorators {} class NoDecorators {}

View File

@ -676,7 +676,8 @@ describe('change detection', () => {
class OnPushComp { class OnPushComp {
/** @Input() */ /** @Input() */
value: string; // TODO(issue/24571): remove '!'.
value !: string;
constructor(public cdr: ChangeDetectorRef) {} constructor(public cdr: ChangeDetectorRef) {}

View File

@ -292,7 +292,8 @@ describe('components & directives', () => {
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
class MyComp { class MyComp {
@Input() name: string; // TODO(issue/24571): remove '!'.
@Input() name !: string;
// NORMATIVE // NORMATIVE
static ngComponentDef = $r3$.ɵdefineComponent({ static ngComponentDef = $r3$.ɵdefineComponent({
@ -416,7 +417,8 @@ describe('components & directives', () => {
` `
}) })
class MyArrayComp { class MyArrayComp {
@Input() names: string[]; // TODO(issue/24571): remove '!'.
@Input() names !: string[];
static ngComponentDef = $r3$.ɵdefineComponent({ static ngComponentDef = $r3$.ɵdefineComponent({
type: MyArrayComp, type: MyArrayComp,
@ -524,7 +526,8 @@ describe('components & directives', () => {
@Component({selector: 'my-comp', template: `{{ num }}`}) @Component({selector: 'my-comp', template: `{{ num }}`})
class MyComp { class MyComp {
num: number; // TODO(issue/24571): remove '!'.
num !: number;
static ngComponentDef = $r3$.ɵdefineComponent({ static ngComponentDef = $r3$.ɵdefineComponent({
type: MyComp, type: MyComp,
@ -646,7 +649,8 @@ describe('components & directives', () => {
` `
}) })
class MyComp { class MyComp {
@Input() names: string[]; // TODO(issue/24571): remove '!'.
@Input() names !: string[];
static ngComponentDef = $r3$.ɵdefineComponent({ static ngComponentDef = $r3$.ɵdefineComponent({
type: MyComp, type: MyComp,
@ -751,7 +755,8 @@ describe('components & directives', () => {
` `
}) })
class ObjectComp { class ObjectComp {
config: {[key: string]: any}; // TODO(issue/24571): remove '!'.
config !: {[key: string]: any};
static ngComponentDef = $r3$.ɵdefineComponent({ static ngComponentDef = $r3$.ɵdefineComponent({
type: ObjectComp, type: ObjectComp,
@ -827,7 +832,8 @@ describe('components & directives', () => {
` `
}) })
class NestedComp { class NestedComp {
config: {[key: string]: any}; // TODO(issue/24571): remove '!'.
config !: {[key: string]: any};
static ngComponentDef = $r3$.ɵdefineComponent({ static ngComponentDef = $r3$.ɵdefineComponent({
type: NestedComp, type: NestedComp,

View File

@ -25,7 +25,8 @@ describe('lifecycle hooks', () => {
@Component({selector: 'lifecycle-comp', template: ``}) @Component({selector: 'lifecycle-comp', template: ``})
class LifecycleComp { class LifecycleComp {
@Input('name') nameMin: string; // TODO(issue/24571): remove '!'.
@Input('name') nameMin !: string;
ngOnChanges() { events.push('changes' + this.nameMin); } ngOnChanges() { events.push('changes' + this.nameMin); }

View File

@ -44,8 +44,10 @@ describe('queries', () => {
` `
}) })
class ViewQueryComponent { class ViewQueryComponent {
@ViewChild(SomeDirective) someDir: SomeDirective; // TODO(issue/24571): remove '!'.
@ViewChildren(SomeDirective) someDirList: QueryList<SomeDirective>; @ViewChild(SomeDirective) someDir !: SomeDirective;
// TODO(issue/24571): remove '!'.
@ViewChildren(SomeDirective) someDirList !: QueryList<SomeDirective>;
// NORMATIVE // NORMATIVE
static ngComponentDef = $r3$.ɵdefineComponent({ static ngComponentDef = $r3$.ɵdefineComponent({
@ -97,8 +99,10 @@ describe('queries', () => {
` `
}) })
class ContentQueryComponent { class ContentQueryComponent {
@ContentChild(SomeDirective) someDir: SomeDirective; // TODO(issue/24571): remove '!'.
@ContentChildren(SomeDirective) someDirList: QueryList<SomeDirective>; @ContentChild(SomeDirective) someDir !: SomeDirective;
// TODO(issue/24571): remove '!'.
@ContentChildren(SomeDirective) someDirList !: QueryList<SomeDirective>;
// NORMATIVE // NORMATIVE
static ngComponentDef = $r3$.ɵdefineComponent({ static ngComponentDef = $r3$.ɵdefineComponent({

View File

@ -27,11 +27,13 @@ describe('template variables', () => {
@Directive({selector: '[forOf]'}) @Directive({selector: '[forOf]'})
class ForOfDirective { class ForOfDirective {
private previous: any[]; // TODO(issue/24571): remove '!'.
private previous !: any[];
constructor(private view: ViewContainerRef, private template: TemplateRef<any>) {} constructor(private view: ViewContainerRef, private template: TemplateRef<any>) {}
@Input() forOf: any[]; // TODO(issue/24571): remove '!'.
@Input() forOf !: any[];
ngOnChanges(simpleChanges: SimpleChanges) { ngOnChanges(simpleChanges: SimpleChanges) {
if ('forOf' in simpleChanges) { if ('forOf' in simpleChanges) {

View File

@ -130,7 +130,8 @@ describe('component with a container', () => {
} }
class WrapperComponent { class WrapperComponent {
items: string[]; // TODO(issue/24571): remove '!'.
items !: string[];
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: WrapperComponent, type: WrapperComponent,
selectors: [['wrapper']], selectors: [['wrapper']],
@ -367,7 +368,8 @@ describe('recursive components', () => {
it('should map inputs minified & unminified names', async() => { it('should map inputs minified & unminified names', async() => {
class TestInputsComponent { class TestInputsComponent {
minifiedName: string; // TODO(issue/24571): remove '!'.
minifiedName !: string;
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: TestInputsComponent, type: TestInputsComponent,
selectors: [['test-inputs']], selectors: [['test-inputs']],

View File

@ -54,7 +54,8 @@ describe('define', () => {
class MyDirective implements OnChanges { class MyDirective implements OnChanges {
public log: Array<string|SimpleChange> = []; public log: Array<string|SimpleChange> = [];
public valA: string = 'initValue'; public valA: string = 'initValue';
public valB: string; // TODO(issue/24571): remove '!'.
public valB !: string;
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
this.log.push('valA', changes['valA']); this.log.push('valA', changes['valA']);

View File

@ -556,7 +556,8 @@ describe('di', () => {
describe('flags', () => { describe('flags', () => {
class DirB { class DirB {
value: string; // TODO(issue/24571): remove '!'.
value !: string;
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: DirB, type: DirB,

View File

@ -61,8 +61,10 @@ describe('directive', () => {
inputs: {test: 'test', other: 'other'} inputs: {test: 'test', other: 'other'}
}); });
testValue: boolean; // TODO(issue/24571): remove '!'.
other: boolean; testValue !: boolean;
// TODO(issue/24571): remove '!'.
other !: boolean;
/** /**
* A setter to assert that a binding is not invoked with stringified attribute value * A setter to assert that a binding is not invoked with stringified attribute value
@ -108,9 +110,12 @@ describe('directive', () => {
inputs: {test: 'test', prop1: 'prop1', prop2: 'prop2'} inputs: {test: 'test', prop1: 'prop1', prop2: 'prop2'}
}); });
prop1: boolean; // TODO(issue/24571): remove '!'.
prop2: boolean; prop1 !: boolean;
testValue: boolean; // TODO(issue/24571): remove '!'.
prop2 !: boolean;
// TODO(issue/24571): remove '!'.
testValue !: boolean;
/** /**

View File

@ -76,7 +76,8 @@ describe('exports', () => {
} }
class MyDir { class MyDir {
myDir: MyComponent; // TODO(issue/24571): remove '!'.
myDir !: MyComponent;
constructor() { myDir = this; } constructor() { myDir = this; }
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: MyDir, type: MyDir,
@ -242,7 +243,8 @@ describe('exports', () => {
} }
class MyDir { class MyDir {
myDir: MyComponent; // TODO(issue/24571): remove '!'.
myDir !: MyComponent;
constructor() { myDir = this; } constructor() { myDir = this; }

View File

@ -459,7 +459,8 @@ class LocalSanitizedValue {
} }
class LocalMockSanitizer implements Sanitizer { class LocalMockSanitizer implements Sanitizer {
public lastSanitizedValue: string|null; // TODO(issue/24571): remove '!'.
public lastSanitizedValue !: string | null;
constructor(private _interceptor: (value: string|null|any) => string) {} constructor(private _interceptor: (value: string|null|any) => string) {}

View File

@ -375,7 +375,8 @@ describe('render3 integration test', () => {
* % } * % }
*/ */
class MyComp { class MyComp {
condition: boolean; // TODO(issue/24571): remove '!'.
condition !: boolean;
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: MyComp, type: MyComp,
selectors: [['comp']], selectors: [['comp']],
@ -491,8 +492,10 @@ describe('render3 integration test', () => {
} }
class ChildComponent { class ChildComponent {
beforeTree: Tree; // TODO(issue/24571): remove '!'.
afterTree: Tree; beforeTree !: Tree;
// TODO(issue/24571): remove '!'.
afterTree !: Tree;
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
selectors: [['child']], selectors: [['child']],
type: ChildComponent, type: ChildComponent,

View File

@ -46,7 +46,8 @@ describe('event listeners', () => {
class PreventDefaultComp { class PreventDefaultComp {
handlerReturnValue: any = true; handlerReturnValue: any = true;
event: Event; // TODO(issue/24571): remove '!'.
event !: Event;
onClick(e: any) { onClick(e: any) {
this.event = e; this.event = e;

View File

@ -358,7 +358,8 @@ describe('outputs', () => {
let otherDir: OtherChangeDir; let otherDir: OtherChangeDir;
class OtherChangeDir { class OtherChangeDir {
change: boolean; // TODO(issue/24571): remove '!'.
change !: boolean;
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: OtherChangeDir, type: OtherChangeDir,

View File

@ -382,10 +382,13 @@ class MultiArgPipe implements PipeTransform {
} }
class Person { class Person {
age: number; // TODO(issue/24571): remove '!'.
name: string|null; age !: number;
// TODO(issue/24571): remove '!'.
name !: string | null;
address: Address|null = null; address: Address|null = null;
phones: number[]; // TODO(issue/24571): remove '!'.
phones !: number[];
init(name: string|null, address: Address|null = null) { init(name: string|null, address: Address|null = null) {
this.name = name; this.name = name;

View File

@ -99,7 +99,8 @@ describe('elementProperty', () => {
let idDir: IdDir; let idDir: IdDir;
class MyButton { class MyButton {
disabled: boolean; // TODO(issue/24571): remove '!'.
disabled !: boolean;
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: MyButton, type: MyButton,
@ -110,7 +111,8 @@ describe('elementProperty', () => {
} }
class OtherDir { class OtherDir {
id: boolean; // TODO(issue/24571): remove '!'.
id !: boolean;
clickStream = new EventEmitter(); clickStream = new EventEmitter();
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
@ -123,7 +125,8 @@ describe('elementProperty', () => {
} }
class OtherDisabledDir { class OtherDisabledDir {
disabled: boolean; // TODO(issue/24571): remove '!'.
disabled !: boolean;
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: OtherDisabledDir, type: OtherDisabledDir,
@ -134,7 +137,8 @@ describe('elementProperty', () => {
} }
class IdDir { class IdDir {
idNumber: number; // TODO(issue/24571): remove '!'.
idNumber !: number;
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: IdDir, type: IdDir,
@ -208,7 +212,8 @@ describe('elementProperty', () => {
let comp: Comp; let comp: Comp;
class Comp { class Comp {
id: number; // TODO(issue/24571): remove '!'.
id !: number;
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: Comp, type: Comp,
@ -358,8 +363,10 @@ describe('elementProperty', () => {
describe('attributes and input properties', () => { describe('attributes and input properties', () => {
let myDir: MyDir; let myDir: MyDir;
class MyDir { class MyDir {
role: string; // TODO(issue/24571): remove '!'.
direction: string; role !: string;
// TODO(issue/24571): remove '!'.
direction !: string;
changeStream = new EventEmitter(); changeStream = new EventEmitter();
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
@ -374,7 +381,8 @@ describe('elementProperty', () => {
let dirB: MyDirB; let dirB: MyDirB;
class MyDirB { class MyDirB {
roleB: string; // TODO(issue/24571): remove '!'.
roleB !: string;
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: MyDirB, type: MyDirB,

View File

@ -15,7 +15,8 @@ describe('array literals', () => {
let myComp: MyComp; let myComp: MyComp;
class MyComp { class MyComp {
names: string[]; // TODO(issue/24571): remove '!'.
names !: string[];
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: MyComp, type: MyComp,
@ -68,8 +69,10 @@ describe('array literals', () => {
let manyPropComp: ManyPropComp; let manyPropComp: ManyPropComp;
class ManyPropComp { class ManyPropComp {
names1: string[]; // TODO(issue/24571): remove '!'.
names2: string[]; names1 !: string[];
// TODO(issue/24571): remove '!'.
names2 !: string[];
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: ManyPropComp, type: ManyPropComp,
@ -331,7 +334,8 @@ describe('object literals', () => {
let objectComp: ObjectComp; let objectComp: ObjectComp;
class ObjectComp { class ObjectComp {
config: {[key: string]: any}; // TODO(issue/24571): remove '!'.
config !: {[key: string]: any};
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: ObjectComp, type: ObjectComp,

Some files were not shown because too many files have changed in this diff Show More