refactor(devtools): add tslint typing rule and fix tslint warnings

This commit is contained in:
AleksanderBodurri 2020-03-04 13:18:52 -05:00 committed by Minko Gechev
parent 50488f9380
commit 5b10bf2e38
28 changed files with 106 additions and 78 deletions

View file

@ -1,11 +1,11 @@
import { browser, by, element } from 'protractor';
export class AppPage {
navigateTo() {
navigateTo(): Promise<any> {
return browser.get(browser.baseUrl) as Promise<any>;
}
getTitleText() {
getTitleText(): Promise<string> {
return element(by.css('app-root .content span')).getText() as Promise<string>;
}
}

View file

@ -77,7 +77,7 @@ export function unHighlight(): void {
}
}
export function inDoc(node): boolean {
export function inDoc(node: any): boolean {
if (!node) {
return false;
}
@ -96,7 +96,17 @@ export function getComponentRect(el: Node): DOMRect | ClientRect {
return el.getBoundingClientRect();
}
function showOverlay({ width = 0, height = 0, top = 0, left = 0 }, content = []): void {
interface OverlayDimensionsAndPosition {
width: number;
height: number;
top: number;
left: number;
}
function showOverlay(
{ width = 0, height = 0, top = 0, left = 0 }: OverlayDimensionsAndPosition,
content: any[] = []
): void {
overlay.style.width = ~~width + 'px';
overlay.style.height = ~~height + 'px';
overlay.style.top = ~~top + 'px';

View file

@ -5,7 +5,7 @@ const TYPE = 1;
const ELEMENT = 0;
const LVIEW_TVIEW = 1;
export function isLContainer(value: any) {
export function isLContainer(value: any): boolean {
return Array.isArray(value) && value[TYPE] === true;
}

View file

@ -9,6 +9,11 @@ interface TreeNode {
children: TreeNode[];
}
type NodeArray = {
directive: any;
isComponent: boolean;
}[];
export class IdentityTracker {
private _directiveIdCounter = 0;
private _currentDirectivePosition = new Map<any, ElementPosition>();
@ -17,22 +22,22 @@ export class IdentityTracker {
constructor(private _ng: DebuggingAPI) {}
getDirectivePosition(dir: any) {
getDirectivePosition(dir: any): ElementPosition {
return this._currentDirectivePosition.get(dir);
}
getDirectiveId(dir: any) {
getDirectiveId(dir: any): number {
return this._currentDirectiveId.get(dir);
}
hasDirective(dir: any) {
hasDirective(dir: any): boolean {
return this._currentDirectiveId.has(dir);
}
index() {
index(): { newNodes: NodeArray; removedNodes: NodeArray; indexedForest: IndexedNode[] } {
const indexedForest = indexForest(buildDirectiveForest(this._ng));
const newNodes: { directive: any; isComponent: boolean }[] = [];
const removedNodes: { directive: any; isComponent: boolean }[] = [];
const newNodes: NodeArray = [];
const removedNodes: NodeArray = [];
const allNodes = new Set<any>();
indexedForest.forEach(root => this._index(root, null, newNodes, allNodes));
this._currentDirectiveId.forEach((_: number, dir: any) => {
@ -66,7 +71,7 @@ export class IdentityTracker {
node.children.forEach(child => this._index(child, parent, newNodes, allNodes));
}
private _indexNode(directive: any, position: ElementPosition, newNodes: { directive: any; isComponent: boolean }[]) {
private _indexNode(directive: any, position: ElementPosition, newNodes: NodeArray): void {
this._currentDirectivePosition.set(directive, position);
if (!this._currentDirectiveId.has(directive)) {
newNodes.push({ directive, isComponent: this._isComponent.get(directive) });
@ -74,7 +79,7 @@ export class IdentityTracker {
}
}
destroy() {
destroy(): void {
this._currentDirectivePosition = new Map<any, ElementPosition>();
this._currentDirectiveId = new Map<any, number>();
}

View file

@ -23,7 +23,7 @@ export const start = (onFrame: (frame: ProfilerFrame) => void): void => {
observer = new ComponentTreeObserver({
// We flush here because it's possible the current node to overwrite
// an existing removed node.
onCreate(directive: any, id: number, isComponent: boolean, position: ElementPosition) {
onCreate(directive: any, id: number, isComponent: boolean, position: ElementPosition): void {
eventMap.set(directive, {
name: getComponentName(directive),
isComponent,
@ -32,7 +32,7 @@ export const start = (onFrame: (frame: ProfilerFrame) => void): void => {
});
insertionTrie.insert(position);
},
onChangeDetection(component: any, id: number, position: ElementPosition, duration: number) {
onChangeDetection(component: any, id: number, position: ElementPosition, duration: number): void {
if (!inChangeDetection) {
inChangeDetection = true;
const source = getChangeDetectionSource();
@ -54,12 +54,18 @@ export const start = (onFrame: (frame: ProfilerFrame) => void): void => {
const profile = eventMap.get(component);
profile.changeDetection += duration;
},
onDestroy(directive: any, id: number, isComponent: boolean, position: ElementPosition) {
onDestroy(directive: any, id: number, isComponent: boolean, position: ElementPosition): void {
if (isComponent) {
removedComponents.set(directive, position);
}
},
onLifecycleHook(directive: any, id: number, isComponent: boolean, hook: keyof LifecycleProfile, duration: number) {
onLifecycleHook(
directive: any,
id: number,
isComponent: boolean,
hook: keyof LifecycleProfile,
duration: number
): void {
if (!eventMap.has(directive)) {
eventMap.set(directive, {
name: getComponentName(directive),

View file

@ -81,15 +81,15 @@ export class ComponentTreeObserver {
constructor(private _config: Partial<Config>) {}
getDirectivePosition(dir: any) {
getDirectivePosition(dir: any): ElementPosition {
return this._tracker.getDirectivePosition(dir);
}
getDirectiveId(dir: any) {
getDirectiveId(dir: any): number {
return this._tracker.getDirectiveId(dir);
}
getDirectiveForest() {
getDirectiveForest(): IndexedNode[] {
return this._forest;
}
@ -101,7 +101,7 @@ export class ComponentTreeObserver {
this._observeUpdates();
}
destroy() {
destroy(): void {
this._mutationObserver.disconnect();
this._lastChangeDetection = new Map<any, number>();
this._tracker.destroy();
@ -117,7 +117,7 @@ export class ComponentTreeObserver {
this._undoLifecyclePatch = [];
}
private _observeUpdates() {
private _observeUpdates(): void {
const { newNodes, removedNodes, indexedForest } = this._tracker.index();
this._forest = indexedForest;
newNodes.forEach(node => {
@ -162,7 +162,7 @@ export class ComponentTreeObserver {
if (original.patched) {
return;
}
declarations.tView.template = function(_: any, component: any) {
declarations.tView.template = function(_: any, component: any): void {
const start = performance.now();
original.apply(this, arguments);
if (self._tracker.hasDirective(component)) {
@ -180,7 +180,7 @@ export class ComponentTreeObserver {
this._patched.set(cmp, original);
}
private _observeLifecycle(directive: any, isComponent: boolean) {
private _observeLifecycle(directive: any, isComponent: boolean): void {
const ctx = directive.__ngContext__;
const tview = ctx[1];
hookTViewProperties.forEach(hook => {
@ -194,7 +194,7 @@ export class ComponentTreeObserver {
}
if (typeof el === 'function') {
const self = this;
current[idx] = function() {
current[idx] = function(): any {
const start = performance.now();
const result = el.apply(this, arguments);
if (self._tracker.hasDirective(this)) {

View file

@ -1,8 +1,8 @@
import { nestedSerializer } from './state-serializer';
const query1_1 = [];
const QUERY_1_1 = [];
const query1_2 = [
const QUERY_1_2 = [
{
name: 'nested',
children: [
@ -63,7 +63,7 @@ const dir2 = {
describe('nestedSerializer', () => {
it('should work with empty queries', () => {
const result = nestedSerializer(dir1, query1_1);
const result = nestedSerializer(dir1, QUERY_1_1);
expect(result).toEqual({
type: 9,
value: {
@ -88,7 +88,7 @@ describe('nestedSerializer', () => {
});
it('should collect not specified but existing props below level', () => {
expect(nestedSerializer(dir1, query1_2)).toEqual({
expect(nestedSerializer(dir1, QUERY_1_2)).toEqual({
type: 9,
value: {
one: {

View file

@ -12,7 +12,7 @@ export const patchTemplate = (instance: any, fn: () => void) => {
const metadata = componentMetadata(instance);
const original = metadata.template;
metadata.tView.template = metadata.template = function() {
metadata.tView.template = metadata.template = function(): any {
const result = original.apply(this, arguments);
fn();
return result;

View file

@ -1,4 +1,4 @@
import { Component, HostListener, Input, OnInit, ViewChild } from '@angular/core';
import { Component, HostListener, Input, OnInit, QueryList, ViewChild } from '@angular/core';
import {
MessageBus,
Events,
@ -16,6 +16,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
import { PropertyTabComponent } from './property-tab/property-tab.component';
import { Subject } from 'rxjs';
import { throttleTime } from 'rxjs/operators';
import { PropertyViewComponent } from './property-tab/property-tab-body/property-view/property-view.component';
@Component({
selector: 'ng-directive-explorer',
@ -37,7 +38,7 @@ export class DirectiveExplorerComponent implements OnInit {
splitDirection = 'horizontal';
private changeSize = new Subject();
private changeSize = new Subject<Event>();
constructor(private _appOperations: ApplicationOperations, private _snackBar: MatSnackBar) {
this.changeSize
@ -120,7 +121,7 @@ export class DirectiveExplorerComponent implements OnInit {
return result;
}
get propertyViews() {
get propertyViews(): QueryList<PropertyViewComponent> {
return this.propertyTab.propertyTabBody.propertyViews;
}
@ -137,21 +138,21 @@ export class DirectiveExplorerComponent implements OnInit {
document.execCommand('copy');
}
handleHighlightFromComponent(position: ElementPosition) {
handleHighlightFromComponent(position: ElementPosition): void {
this.messageBus.emit('highlightElementFromComponentTree', [position]);
}
handleUnhighlightFromComponent(_: ElementPosition | null) {
handleUnhighlightFromComponent(_: ElementPosition | null): void {
this.messageBus.emit('removeHighlightFromElement');
}
@HostListener('window:resize', ['$event'])
onResize(event) {
onResize(event: Event): void {
this.changeSize.next(event);
}
handleResize(event) {
if (event.target.innerWidth <= 500) {
handleResize(event: Event): void {
if ((event.target as any).innerWidth <= 500) {
this.splitDirection = 'vertical';
} else {
this.splitDirection = 'horizontal';

View file

@ -76,11 +76,11 @@ export class ComponentDataSource extends DataSource<FlatNode> {
return this._flattenedData.value;
}
get expandedDataValues() {
get expandedDataValues(): FlatNode[] {
return this._expandedData.value;
}
update(forest: DevToolsNode[]) {
update(forest: DevToolsNode[]): FlatNode[] {
if (!forest) {
return;
}
@ -110,5 +110,5 @@ export class ComponentDataSource extends DataSource<FlatNode> {
);
}
disconnect() {}
disconnect(): void {}
}

View file

@ -12,15 +12,15 @@ export class FilterComponent {
@Input() hasMatched = false;
emitFilter(event: InputEvent) {
emitFilter(event: InputEvent): void {
this.filter.emit((event.target as HTMLInputElement).value);
}
emitNextMatched() {
emitNextMatched(): void {
this.nextMatched.emit();
}
emitPrevMatched() {
emitPrevMatched(): void {
this.prevMatched.emit();
}
}

View file

@ -86,7 +86,7 @@ export class ProfilerComponent implements OnInit, OnDestroy {
this._fileApiService.uploadedData.unsubscribe();
}
private _viewProfilerData(stream): void {
private _viewProfilerData(stream: ProfilerFrame[]): void {
this.state = 'visualizing';
this.stream = stream;
}

View file

@ -18,11 +18,11 @@ export class RecordingVisualizerComponent {
constructor(private _el: ElementRef) {}
selectFrame(frame: RawData) {
selectFrame(frame: RawData): void {
this.selectedEntry = frame as FlamegraphNode;
}
get availableWidth() {
get availableWidth(): number {
return this._el.nativeElement.querySelector('.level-profile-wrapper').offsetWidth;
}
}

View file

@ -27,12 +27,12 @@ export class TimelineComponent {
return this.profileRecords.timeline[this.currentView] || { app: [], timeSpent: 0, source: '' };
}
frameRate(timeSpent: number) {
frameRate(timeSpent: number): number {
const multiplier = Math.max(Math.ceil(timeSpent / 16) - 1, 0);
return Math.floor(64 / 2 ** multiplier);
}
updateView($event: MatSliderChange) {
updateView($event: MatSliderChange): void {
if ($event.value === undefined || $event.value > this.profileRecords.timeline.length) {
return;
}

View file

@ -72,11 +72,11 @@ export class PropertyDataSource extends DataSource<FlatNode> {
this._data.next(this.treeFlattener.flattenNodes(this._arrayify(props)));
}
get data() {
get data(): FlatNode[] {
return this._data.value;
}
update(props: { [prop: string]: Descriptor }) {
update(props: { [prop: string]: Descriptor }): void {
const newData = this.treeFlattener.flattenNodes(this._arrayify(props));
diff(this._differ, this.data, newData);
@ -109,16 +109,16 @@ export class PropertyDataSource extends DataSource<FlatNode> {
);
}
disconnect() {
disconnect(): void {
this._subscriptions.forEach(s => s.unsubscribe());
this._subscriptions = [];
}
private _arrayify(props: { [prop: string]: Descriptor }, parent: Property = null) {
private _arrayify(props: { [prop: string]: Descriptor }, parent: Property = null): Property[] {
return Object.keys(props).map(name => ({ name, descriptor: props[name], parent }));
}
private _toggleNode(node: FlatNode, expand: boolean) {
private _toggleNode(node: FlatNode, expand: boolean): void {
const index = this.data.indexOf(node);
// If we cannot find the current node, or the current node is not expandable
// or...if it's expandable but it does have a value, or we're collapsing
@ -151,7 +151,7 @@ export class PropertyDataSource extends DataSource<FlatNode> {
});
}
private _getChildren(prop: Property) {
private _getChildren(prop: Property): Property[] {
const descriptor = prop.descriptor;
if (descriptor.type === PropType.Object && !(descriptor.value instanceof Observable)) {
return Object.keys(descriptor.value || {}).map(name => {

View file

@ -106,7 +106,7 @@ export class PropertyEditorComponent implements OnChanges, AfterViewChecked {
this.transition(PropertyEditorState.Read);
}
private parseValue(value: EditorResult) {
private parseValue(value: EditorResult): EditorResult {
if (value === 'undefined') {
return undefined;
} else {

View file

@ -4,6 +4,11 @@ import { FlatTreeControl } from '@angular/cdk/tree';
import { FlatNode, Property, PropertyDataSource } from './property-data-source';
import { getExpandedDirectiveProperties } from './property-expanded-directive-properties';
interface UpdatedValueProperties {
key: string;
newValue: any;
}
@Component({
selector: `ng-property-view`,
templateUrl: './property-view.component.html',
@ -51,7 +56,7 @@ export class PropertyViewComponent {
return getExpandedDirectiveProperties(this.dataSource.data);
}
updateValue({ key, newValue }, node): void {
updateValue({ key, newValue }: UpdatedValueProperties, node: FlatNode): void {
const directiveId = this.entityID;
const keyPath = this._constructPathOfKeysToPropertyValue(node.prop);
this.messageBus.emit('updateState', [{ directiveId, keyPath, newValue }]);

View file

@ -1,11 +1,11 @@
import { browser, by, element } from 'protractor';
export class AppPage {
navigateTo() {
navigateTo(): Promise<any> {
return browser.get(browser.baseUrl) as Promise<any>;
}
getTitleText() {
getTitleText(): Promise<string> {
return element(by.css('app-root .content span')).getText() as Promise<string>;
}
}

View file

@ -4,7 +4,7 @@ window.addEventListener('message', (event: MessageEvent) => {
}
});
function detectAngular(win: Window) {
function detectAngular(win: Window): void {
const isDebugMode = Boolean((win as any).ng);
const ngVersionElement = document.querySelector('[ng-version]');
const isSupportedAngularVersion = ngVersionElement
@ -20,7 +20,7 @@ function detectAngular(win: Window) {
);
}
function installScript(fn: string) {
function installScript(fn: string): void {
const source = `;(${fn})(window)`;
const script = document.createElement('script');
script.textContent = source;

View file

@ -12,7 +12,7 @@ export class ZoneAwareChromeMessageBus extends MessageBus<Events> {
on<E extends keyof Events>(topic: E, cb: Events[E]): void {
this._bus.on(
topic,
function() {
function(): void {
this._ngZone.run(() => cb.apply(null, arguments));
}.bind(this)
);
@ -21,7 +21,7 @@ export class ZoneAwareChromeMessageBus extends MessageBus<Events> {
once<E extends keyof Events>(topic: E, cb: Events[E]): void {
this._bus.once(
topic,
function() {
function(): void {
this._ngZone.run(() => cb.apply(null, arguments));
}.bind(this)
);

View file

@ -1,15 +1,15 @@
let reloadFns: ((url: string) => void)[] = [];
export const panelDevTools = {
injectBackend(cb?: () => void) {
injectBackend(cb?: () => void): void {
injectScripts(['backend.js', 'runtime.js'], cb);
},
onReload(reloadFn: (url: string) => void) {
onReload(reloadFn: (url: string) => void): void {
reloadFns.push(reloadFn);
chrome.devtools.network.onNavigated.addListener(reloadFn);
},
destroy() {
destroy(): void {
reloadFns.forEach(f => chrome.devtools.network.onNavigated.removeListener(f));
reloadFns = [];
},

View file

@ -8,7 +8,7 @@ import { ZippyComponent } from './zippy/zippy.component';
export class DemoAppComponent {
@ViewChild(ZippyComponent) zippy: ZippyComponent;
getTitle() {
getTitle(): '► Click to expand' | '▼ Click to collapse' {
if (!this.zippy || !this.zippy.visible) {
return '► Click to expand';
}

View file

@ -13,7 +13,7 @@ const fib = (n: number) => {
styleUrls: ['./heavy.component.css'],
})
export class HeavyComponent {
calculate() {
calculate(): number {
return fib(15);
}
}

View file

@ -12,7 +12,7 @@ export const enum TodoFilter {
name: 'todosFilter',
})
export class TodosFilter implements PipeTransform {
transform(todos: Todo[], filter: TodoFilter) {
transform(todos: Todo[], filter: TodoFilter): Todo[] {
return (todos || []).filter(t => {
if (filter === TodoFilter.All) {
return true;

View file

@ -9,7 +9,7 @@ export class DevToolsComponent implements AfterViewInit {
messageBus: IFrameMessageBus | null = null;
@ViewChild('ref') iframe: ElementRef;
ngAfterViewInit() {
ngAfterViewInit(): void {
setTimeout(() => {
this.messageBus = new IFrameMessageBus(
'angular-devtools',

View file

@ -9,7 +9,7 @@ export class IFrameMessageBus extends MessageBus<Events> {
super();
}
onAny(cb: AnyEventCallback<Events>) {
onAny(cb: AnyEventCallback<Events>): () => void {
const listener = (e: MessageEvent) => {
if (!e.data || !e.data.topic || e.data.source !== this._destination) {
return;
@ -24,7 +24,7 @@ export class IFrameMessageBus extends MessageBus<Events> {
};
}
on<E extends keyof Events>(topic: E, cb: Events[E]) {
on<E extends keyof Events>(topic: E, cb: Events[E]): () => void {
const listener = (e: MessageEvent) => {
if (!e.data || e.data.source !== this._destination || !e.data.topic) {
return;
@ -41,7 +41,7 @@ export class IFrameMessageBus extends MessageBus<Events> {
};
}
once<E extends keyof Events>(topic: E, cb: Events[E]) {
once<E extends keyof Events>(topic: E, cb: Events[E]): void {
const listener = (e: MessageEvent) => {
if (!e.data || e.data.source !== this._destination || !e.data.topic) {
return;

View file

@ -19,7 +19,7 @@ export class ZoneUnawareIFrameMessageBus extends MessageBus<Events> {
this._delegate = new IFrameMessageBus(source, destination, docWindow);
}
onAny(cb: AnyEventCallback<Events>) {
onAny(cb: AnyEventCallback<Events>): any {
let result: any;
runOutsideAngular(() => {
result = this._delegate.onAny(cb);
@ -27,7 +27,7 @@ export class ZoneUnawareIFrameMessageBus extends MessageBus<Events> {
return result;
}
on<E extends keyof Events>(topic: E, cb: Events[E]) {
on<E extends keyof Events>(topic: E, cb: Events[E]): any {
let result: any;
runOutsideAngular(() => {
result = this._delegate.on(topic, cb);
@ -35,7 +35,7 @@ export class ZoneUnawareIFrameMessageBus extends MessageBus<Events> {
return result;
}
once<E extends keyof Events>(topic: E, cb: Events[E]) {
once<E extends keyof Events>(topic: E, cb: Events[E]): any {
let result: any;
runOutsideAngular(() => {
result = this._delegate.once(topic, cb);
@ -49,7 +49,7 @@ export class ZoneUnawareIFrameMessageBus extends MessageBus<Events> {
return this._delegate.emit(topic, args);
}
destroy() {
destroy(): void {
this._delegate.destroy();
}
}

View file

@ -48,7 +48,8 @@
"template-banana-in-box": true,
"template-no-negated-async": true,
"use-lifecycle-interface": true,
"use-pipe-transform-interface": true
"use-pipe-transform-interface": true,
"typedef": [true, "parameter", "call-signature", "property-declaration"]
},
"rulesDirectory": ["node_modules/codelyzer"]
}