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 {
public duration: number = 0;
public easing: string|null;
// TODO(issue/24571): remove '!'.
public easing !: string | null;
private _previousKeyframe: ɵStyleData = {};
private _currentKeyframe: ɵStyleData = {};
private _keyframes = new Map<number, ɵStyleData>();

View File

@ -23,9 +23,11 @@ export class CssKeyframesPlayer implements AnimationPlayer {
private _onDestroyFns: Function[] = [];
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 easing: string;
public currentSnapshot: {[key: string]: string} = {};

View File

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

View File

@ -21,9 +21,11 @@ export class WebAnimationsPlayer implements AnimationPlayer {
private _finished = false;
private _started = 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 parentPlayer: AnimationPlayer|null = null;

View File

@ -12,8 +12,10 @@ const ParserUtil = require('./parser_util');
class Profiler {
private _profiler: any;
private _markerEvents: any[];
private _profilerStartTime: number;
// TODO(issue/24571): remove '!'.
private _markerEvents !: any[];
// TODO(issue/24571): remove '!'.
private _profilerStartTime !: number;
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.
*/
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).
*/
private lazyInit: HttpHeaders|Function|null;
// TODO(issue/24571): remove '!'.
private lazyInit !: HttpHeaders | Function | null;
/**
* Queued updates to be materialized the next initialization.

View File

@ -88,7 +88,8 @@ export class HttpRequest<T> {
/**
* 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.
@ -119,7 +120,8 @@ export class HttpRequest<T> {
/**
* Outgoing URL parameters.
*/
readonly params: HttpParams;
// TODO(issue/24571): remove '!'.
readonly params !: HttpParams;
/**
* 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.
*/
readonly type: HttpEventType.Response|HttpEventType.ResponseHeader;
// TODO(issue/24571): remove '!'.
readonly type !: HttpEventType.Response | HttpEventType.ResponseHeader;
/**
* Super-constructor for all responses.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -34,11 +34,14 @@ import {Directive, EmbeddedViewRef, Input, OnChanges, SimpleChange, SimpleChange
*/
@Directive({selector: '[ngTemplateOutlet]'})
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) {}

View File

@ -42,8 +42,10 @@ export interface KeyValue<K, V> {
export class KeyValuePipe implements PipeTransform {
constructor(private readonly differs: KeyValueDiffers) {}
private differ: KeyValueDiffer<any, any>;
private keyValues: Array<KeyValue<any, any>>;
// TODO(issue/24571): remove '!'.
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<V>(

View File

@ -358,7 +358,8 @@ import {ComponentFixture, TestBed, async} from '@angular/core/testing';
@Component({selector: 'test-cmp', template: ''})
class TestComponent {
condition: boolean = true;
items: any[];
// TODO(issue/24571): remove '!'.
items !: any[];
arrExpr: string[] = ['foo'];
setExpr: Set<string> = new Set<string>();
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>`;
@Component({selector: 'test-cmp', template: TEST_CMP_TEMPLATE})
class TestComponent {
currentComponent: Type<any>|null;
injector: Injector;
projectables: any[][];
module: NgModuleFactory<any>;
// TODO(issue/24571): remove '!'.
currentComponent !: Type<any>| null;
// TODO(issue/24571): remove '!'.
injector !: Injector;
// TODO(issue/24571): remove '!'.
projectables !: any[][];
// TODO(issue/24571): remove '!'.
module !: NgModuleFactory<any>;
get cmpRef(): ComponentRef<any>|null { return this.ngComponentOutlet['_componentRef']; }
set cmpRef(value: ComponentRef<any>|null) { this.ngComponentOutlet['_componentRef'] = value; }
@ViewChildren(TemplateRef) tplRefs: QueryList<TemplateRef<any>>;
@ViewChild(NgComponentOutlet) ngComponentOutlet: NgComponentOutlet;
// TODO(issue/24571): remove '!'.
@ViewChildren(TemplateRef) tplRefs !: QueryList<TemplateRef<any>>;
// TODO(issue/24571): remove '!'.
@ViewChild(NgComponentOutlet) ngComponentOutlet !: NgComponentOutlet;
constructor(public vcRef: ViewContainerRef) {}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -23,7 +23,8 @@ export class TypeDiagnostic {
// AstType calculatetype of the ast given AST element.
export class AstType implements AstVisitor {
public diagnostics: TypeDiagnostic[];
// TODO(issue/24571): remove '!'.
public diagnostics !: TypeDiagnostic[];
constructor(
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);
}
private _anyType: Symbol;
// TODO(issue/24571): remove '!'.
private _anyType !: Symbol;
private get anyType(): Symbol {
let result = this._anyType;
if (!result) {
@ -343,7 +345,8 @@ export class AstType implements AstVisitor {
return result;
}
private _undefinedType: Symbol;
// TODO(issue/24571): remove '!'.
private _undefinedType !: Symbol;
private get undefinedType(): Symbol {
let result = this._undefinedType;
if (!result) {

View File

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

View File

@ -85,7 +85,8 @@ export class MetadataBundler {
private exports = new Map<string, Symbol[]>();
private rootModule: string;
private privateSymbolPrefix: string;
private exported: Set<Symbol>;
// TODO(issue/24571): remove '!'.
private exported !: Set<Symbol>;
constructor(
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';
export class Symbols {
private _symbols: Map<string, MetadataValue>;
// TODO(issue/24571): remove '!'.
private _symbols !: Map<string, MetadataValue>;
private references = new Map<string, MetadataSymbolicReferenceExpression>();
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.
*/
readonly expressable: boolean;
// TODO(issue/24571): remove '!'.
readonly expressable !: boolean;
/**
* 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,
// 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);
dtsTransformer.recordStaticField(reflectNameOfDeclaration(node) !, res);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -112,7 +112,8 @@ export class Xliff2 extends Serializer {
}
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)]; }
@ -190,9 +191,12 @@ class _WriteVisitor implements i18n.Visitor {
// Extract messages as xml nodes from the xliff file
class Xliff2Parser implements ml.Visitor {
private _unitMlString: string|null;
private _errors: I18nError[];
private _msgIdToHtml: {[msgId: string]: string};
// TODO(issue/24571): remove '!'.
private _unitMlString !: string | null;
// TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
// TODO(issue/24571): remove '!'.
private _msgIdToHtml !: {[msgId: string]: string};
private _locale: string|null = null;
parse(xliff: string, url: string) {
@ -285,7 +289,8 @@ class Xliff2Parser implements ml.Visitor {
// Convert ml nodes (xliff syntax) to i18n nodes
class XmlToI18n implements ml.Visitor {
private _errors: I18nError[];
// TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
convert(message: string, url: string) {
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
class XtbParser implements ml.Visitor {
private _bundleDepth: number;
private _errors: I18nError[];
private _msgIdToHtml: {[msgId: string]: string};
// TODO(issue/24571): remove '!'.
private _bundleDepth !: number;
// TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
// TODO(issue/24571): remove '!'.
private _msgIdToHtml !: {[msgId: string]: string};
private _locale: string|null = null;
parse(xtb: string, url: string) {
@ -152,7 +155,8 @@ class XtbParser implements ml.Visitor {
// Convert ml nodes (xtb syntax) to i18n nodes
class XmlToI18n implements ml.Visitor {
private _errors: I18nError[];
// TODO(issue/24571): remove '!'.
private _errors !: I18nError[];
convert(message: string, url: string) {
const xmlIcu = new XmlParser().parse(message, url, true);

View File

@ -60,10 +60,12 @@ export class TranslationBundle {
}
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 _errors: I18nError[] = [];
private _mapper: (name: string) => string;
// TODO(issue/24571): remove '!'.
private _mapper !: (name: string) => string;
constructor(
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} = {};
closedByParent: boolean = false;
requiredParents: {[key: string]: boolean};
parentToAdd: string;
// TODO(issue/24571): remove '!'.
requiredParents !: {[key: string]: boolean};
// TODO(issue/24571): remove '!'.
parentToAdd !: string;
implicitNamespacePrefix: string|null;
contentType: TagContentType;
isVoid: boolean;

View File

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

View File

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

View File

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

View File

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

View File

@ -19,9 +19,12 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
template: '',
})
export class I18nComponent {
count: number;
sex: string;
sexB: string;
// TODO(issue/24571): remove '!'.
count !: number;
// TODO(issue/24571): remove '!'.
sex !: string;
// TODO(issue/24571): remove '!'.
sexB !: string;
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(() => {
@Directive({selector: '[dot.name]'})
class MyDir {
@Input('dot.name') value: string;
// TODO(issue/24571): remove '!'.
@Input('dot.name') value !: string;
}
TestBed.configureTestingModule({

View File

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

View File

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

View File

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

View File

@ -27,7 +27,8 @@ const trackByIdentity = (index: number, item: any) => item;
*/
export class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChanges<V> {
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)
private _linkedRecords: _DuplicateMap<V>|null = null;
// 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 {
nativeNode: any;
listeners: EventListener[];
parent: DebugElement|null;
// TODO(issue/24571): remove '!'.
parent !: DebugElement | null;
constructor(nativeNode: any, parent: DebugNode|null, private _debugContext: DebugContext) {
this.nativeNode = nativeNode;
@ -46,7 +47,8 @@ export class DebugNode {
* @experimental All debugging apis are currently experimental.
*/
export class DebugElement extends DebugNode {
name: string;
// TODO(issue/24571): remove '!'.
name !: string;
properties: {[key: string]: any};
attributes: {[key: string]: string | null};
classes: {[key: string]: boolean};

View File

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

View File

@ -159,7 +159,8 @@ export abstract class Renderer2 {
* in which case the view engine won't call it.
* 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 insertBefore(parent: any, newChild: any, refChild: 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 {
private _viewRefs: viewEngine_ViewRef[] = [];
element: viewEngine_ElementRef;
injector: Injector;
parentInjector: Injector;
// TODO(issue/24571): remove '!'.
element !: viewEngine_ElementRef;
// TODO(issue/24571): remove '!'.
injector !: Injector;
// TODO(issue/24571): remove '!'.
parentInjector !: Injector;
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,
viewEngine_ChangeDetectorRef_interface {
private _appRef: ApplicationRef|null;
// TODO(issue/24571): remove '!'.
private _appRef !: ApplicationRef | null;
context: T;
rootNodes: any[];
// TODO(issue/24571): remove '!'.
rootNodes !: any[];
constructor(protected _view: LViewData, context: T|null) { this.context = context !; }

View File

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

View File

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

View File

@ -1049,7 +1049,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
])]
})
class Cmp {
public items: any[];
// TODO(issue/24571): remove '!'.
public items !: any[];
}
TestBed.configureTestingModule({declarations: [Cmp]});
@ -1129,7 +1130,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
})
class Cmp {
public exp: any;
public items: any[];
// TODO(issue/24571): remove '!'.
public items !: any[];
}
TestBed.configureTestingModule({declarations: [Cmp]});
@ -1349,7 +1351,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
})
class Cmp {
public exp: any;
public items: any[];
// TODO(issue/24571): remove '!'.
public items !: any[];
}
TestBed.configureTestingModule({declarations: [Cmp]});
@ -1401,7 +1404,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
})
class Cmp {
public exp: any;
public items: any[];
// TODO(issue/24571): remove '!'.
public items !: any[];
}
TestBed.configureTestingModule({declarations: [Cmp]});
@ -1463,7 +1467,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
class Cmp {
public exp1: any;
public exp2: any;
public items: any[];
// TODO(issue/24571): remove '!'.
public items !: any[];
}
TestBed.configureTestingModule({declarations: [Cmp]});
@ -1532,7 +1537,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
})
class Cmp {
public exp: any;
public items: any[];
// TODO(issue/24571): remove '!'.
public items !: any[];
}
TestBed.configureTestingModule({declarations: [Cmp]});
@ -1586,7 +1592,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
})
class Cmp {
public exp: any;
public items: any[];
// TODO(issue/24571): remove '!'.
public items !: any[];
}
TestBed.configureTestingModule({declarations: [Cmp]});
@ -2469,7 +2476,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
`
})
class Cmp {
public exp: boolean;
// TODO(issue/24571): remove '!'.
public exp !: boolean;
}
TestBed.configureTestingModule({declarations: [Cmp]});
@ -2648,7 +2656,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
`
})
class Cmp {
public exp: boolean;
// TODO(issue/24571): remove '!'.
public exp !: boolean;
public log: string[] = [];
callback(event: any) {
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: '*'}))])])]
})
class Cmp {
public exp: number;
// TODO(issue/24571): remove '!'.
public exp !: number;
public items = [0, 1, 2, 3, 4];
}
@ -358,7 +359,8 @@ import {TestBed} from '../../testing';
]
})
class Cmp {
public exp: string;
// TODO(issue/24571): remove '!'.
public exp !: string;
}
TestBed.configureTestingModule({declarations: [Cmp]});
@ -411,7 +413,8 @@ import {TestBed} from '../../testing';
]
})
class Cmp {
public exp: string;
// TODO(issue/24571): remove '!'.
public exp !: string;
public items: any[] = [];
}

View File

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

View File

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

View File

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

View File

@ -46,7 +46,8 @@ class App {
template: `{{frame.name}}(<span *ngFor="let lock of locks">{{lock.name}}</span>)`,
})
class Door {
@ContentChildren(forwardRef(() => Lock)) locks: QueryList<Lock>;
// TODO(issue/24571): remove '!'.
@ContentChildren(forwardRef(() => Lock)) locks !: QueryList<Lock>;
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>'})
class Comp {
name = 'Tom';
@ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
@ViewChild(TemplateRef) template: TemplateRef<any>;
// TODO(issue/24571): remove '!'.
@ViewChild('vc', {read: ViewContainerRef}) vc !: ViewContainerRef;
// TODO(issue/24571): remove '!'.
@ViewChild(TemplateRef) template !: TemplateRef<any>;
}
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>`
})
class OuterComp {
// TODO(issue/24571): remove '!'.
@ContentChild(TemplateRef)
tpl: TemplateRef<any>;
tpl !: TemplateRef<any>;
constructor(public cdRef: ChangeDetectorRef) {}
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>`
})
class InnerComp {
// TODO(issue/24571): remove '!'.
@ContentChild(TemplateRef)
tpl: TemplateRef<any>;
tpl !: TemplateRef<any>;
// TODO(issue/24571): remove '!'.
@Input()
outerTpl: TemplateRef<any>;
outerTpl !: TemplateRef<any>;
constructor(public cdRef: ChangeDetectorRef) {}
log(id: string) { log.push(`inner-${id}`); }
@ -1517,7 +1522,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
class MyChild {
private thrown = LifetimeMethods.None;
@Input() inp: boolean;
// TODO(issue/24571): remove '!'.
@Input() inp !: boolean;
@Output() outp = new EventEmitter<any>();
constructor() {}
@ -1793,13 +1799,16 @@ class TestDirective implements OnInit, DoCheck, OnChanges, AfterContentInit, Aft
AfterViewInit, AfterViewChecked, OnDestroy {
@Input() a: any;
@Input() b: any;
changes: SimpleChanges;
// TODO(issue/24571): remove '!'.
changes !: SimpleChanges;
event: any;
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) {}
@ -1875,7 +1884,8 @@ class OnDestroyDirective implements OnDestroy {
@Directive({selector: '[orderCheck0]'})
class OrderCheckDirective0 {
private _name: string;
// TODO(issue/24571): remove '!'.
private _name !: string;
@Input('orderCheck0')
set name(value: string) {
@ -1888,7 +1898,8 @@ class OrderCheckDirective0 {
@Directive({selector: '[orderCheck1]'})
class OrderCheckDirective1 {
private _name: string;
// TODO(issue/24571): remove '!'.
private _name !: string;
@Input('orderCheck1')
set name(value: string) {
@ -1901,7 +1912,8 @@ class OrderCheckDirective1 {
@Directive({selector: '[orderCheck2]'})
class OrderCheckDirective2 {
private _name: string;
// TODO(issue/24571): remove '!'.
private _name !: string;
@Input('orderCheck2')
set name(value: string) {
@ -1925,10 +1937,13 @@ class TestLocals {
@Component({selector: 'root', template: 'empty'})
class Person {
age: number;
name: string;
// TODO(issue/24571): remove '!'.
age !: number;
// TODO(issue/24571): remove '!'.
name !: string;
address: Address|null = null;
phones: number[];
// TODO(issue/24571): remove '!'.
phones !: number[];
init(name: string, address: Address|null = null) {
this.name = name;
@ -1982,13 +1997,15 @@ class TestData {
@Component({selector: 'root', template: 'empty'})
class TestDataWithGetter {
public fn: Function;
// TODO(issue/24571): remove '!'.
public fn !: Function;
get a() { return this.fn(); }
}
class Holder<T> {
value: T;
// TODO(issue/24571): remove '!'.
value !: T;
}
@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)'}})
class DirectiveWithHostListener {
id = 'one';
receivedArgs: any[];
// TODO(issue/24571): remove '!'.
receivedArgs !: any[];
doIt(...args: any[]) { this.receivedArgs = args; }
}
@ -1956,12 +1957,14 @@ class MyDir {
@Directive({selector: '[title]', inputs: ['title']})
class DirectiveWithTitle {
title: string;
// TODO(issue/24571): remove '!'.
title !: string;
}
@Directive({selector: '[title]', inputs: ['title'], host: {'[title]': 'title'}})
class DirectiveWithTitleAndHostProperty {
title: string;
// TODO(issue/24571): remove '!'.
title !: string;
}
@Component({selector: 'event-cmp', template: '<div (click)="noop()"></div>'})
@ -2032,7 +2035,8 @@ class PushCmpWithHostEvent {
})
class PushCmpWithAsyncPipe {
numberOfChecks: number = 0;
resolve: (result: any) => void;
// TODO(issue/24571): remove '!'.
resolve !: (result: any) => void;
promise: Promise<any>;
constructor() {
@ -2218,7 +2222,8 @@ class DirectiveListeningDomEventNoPrevent {
@Directive({selector: '[id]', inputs: ['id']})
class IdDir {
id: string;
// TODO(issue/24571): remove '!'.
id !: string;
}
@Directive({selector: '[customEvent]'})
@ -2281,7 +2286,8 @@ class ToolbarViewContainer {
template: 'TOOLBAR(<div *ngFor="let part of query" [toolbarVc]="part"></div>)',
})
class ToolbarComponent {
@ContentChildren(ToolbarPart) query: QueryList<ToolbarPart>;
// TODO(issue/24571): remove '!'.
@ContentChildren(ToolbarPart) query !: QueryList<ToolbarPart>;
ctxProp: string = 'hello world';
constructor() {}
@ -2481,10 +2487,12 @@ class ComponentWithTemplate {
class DirectiveWithPropDecorators {
target: any;
@Input('elProp') dirProp: string;
// TODO(issue/24571): remove '!'.
@Input('elProp') dirProp !: string;
@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'])
onClick(target: any) { this.target = target; }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -76,26 +76,31 @@ import {TestBed} from '@angular/core/testing';
@Directive({selector: 'simple'})
class Simple {
@Input() marker: string;
// TODO(issue/24571): remove '!'.
@Input() marker !: string;
}
@Component({selector: 'view-child-type-selector', template: ''})
class ViewChildTypeSelectorComponent {
@ViewChild(Simple) child: Simple;
// TODO(issue/24571): remove '!'.
@ViewChild(Simple) child !: Simple;
}
@Component({selector: 'view-child-string-selector', template: ''})
class ViewChildStringSelectorComponent {
@ViewChild('child') child: ElementRef;
// TODO(issue/24571): remove '!'.
@ViewChild('child') child !: ElementRef;
}
@Component({selector: 'view-children-type-selector', template: ''})
class ViewChildrenTypeSelectorComponent {
@ViewChildren(Simple) children: QueryList<Simple>;
// TODO(issue/24571): remove '!'.
@ViewChildren(Simple) children !: QueryList<Simple>;
}
@Component({selector: 'view-child-string-selector', template: ''})
class ViewChildrenStringSelectorComponent {
// 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 Parent {
// TODO(issue/24571): remove '!'.
@PropDecorator('a')
a: A;
a !: A;
// TODO(issue/24571): remove '!'.
@PropDecorator('b1')
b: B;
b !: B;
}
class Child extends Parent {
// TODO(issue/24571): remove '!'.
@PropDecorator('b2')
b: B;
b !: B;
// TODO(issue/24571): remove '!'.
@PropDecorator('c')
c: C;
c !: C;
}
class NoDecorators {}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -61,8 +61,10 @@ describe('directive', () => {
inputs: {test: 'test', other: 'other'}
});
testValue: boolean;
other: boolean;
// TODO(issue/24571): remove '!'.
testValue !: boolean;
// TODO(issue/24571): remove '!'.
other !: boolean;
/**
* 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'}
});
prop1: boolean;
prop2: boolean;
testValue: boolean;
// TODO(issue/24571): remove '!'.
prop1 !: boolean;
// TODO(issue/24571): remove '!'.
prop2 !: boolean;
// TODO(issue/24571): remove '!'.
testValue !: boolean;
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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