Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit f792e7e

Browse files
Splaktarjelbourn
authored andcommitted
refactor: enable stricter TypeScript compiler flags (#631)
align with the examples and the new CLI settings by enabling - `noImplicitAny` - `noImplicitReturns` - `noImplicitThis` - `noFallthroughCasesInSwitch` - `strictNullChecks` Relates to angular/angular-cli#14905
1 parent f5f6c86 commit f792e7e

File tree

19 files changed

+101
-74
lines changed

19 files changed

+101
-74
lines changed

src/app/pages/component-list/component-list.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ import {combineLatest} from 'rxjs';
1616
styleUrls: ['./component-list.scss']
1717
})
1818
export class ComponentList {
19-
category: DocCategory;
19+
category: DocCategory | undefined;
2020
section: string;
2121

2222
constructor(public docItems: DocumentationItems,
2323
private _componentPageTitle: ComponentPageTitle,
2424
private _route: ActivatedRoute,
2525
public router: Router) {
2626
combineLatest(_route.pathFromRoot.map(route => route.params), Object.assign)
27-
.subscribe(p => {
28-
this.category = docItems.getCategoryById(p['id']);
29-
this.section = p['section'];
27+
.subscribe((routeData: {[key: string]: string}) => {
28+
this.category = docItems.getCategoryById(routeData['id']);
29+
this.section = routeData['section'];
3030

3131
if (this.category) {
3232
this._componentPageTitle.title = this.category.name;

src/app/pages/component-sidenav/component-sidenav.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export class ComponentSidenav implements OnInit {
6060
export class ComponentNav implements OnInit, OnDestroy {
6161

6262
@Input() params: Observable<Params>;
63-
expansions = {};
63+
expansions: {[key: string]: boolean} = {};
6464
private _onDestroy = new Subject<void>();
6565

6666
constructor(public docItems: DocumentationItems,
@@ -83,7 +83,7 @@ export class ComponentNav implements OnInit, OnDestroy {
8383
setExpansions(params: Params) {
8484
const categories = this.docItems.getCategories(params.section);
8585
for (const category of (categories || [])) {
86-
if (this.expansions[category.id] === true) {
86+
if (this.expansions[category.id]) {
8787
continue;
8888
}
8989

@@ -95,7 +95,7 @@ export class ComponentNav implements OnInit, OnDestroy {
9595
}
9696
}
9797

98-
if (this.expansions[category.id] === false) {
98+
if (!this.expansions[category.id]) {
9999
this.expansions[category.id] = match;
100100
}
101101
}

src/app/pages/component-viewer/component-viewer.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ describe('ComponentViewer', () => {
4141
it('should set page title correctly', () => {
4242
const component = fixture.componentInstance;
4343
fixture.detectChanges();
44-
const expected = `${component.docItems.getItemById(docItemsId, 'material').name}`;
44+
const docItem = component.docItems.getItemById(docItemsId, 'material');
45+
if (docItem === undefined) {
46+
throw Error(`Unable to find DocItem: '${docItemsId}' in section: 'material'.`);
47+
}
48+
const expected = `${docItem.name}`;
4549
expect(component._componentPageTitle.title).toEqual(expected);
4650
});
4751
});

src/app/pages/component-viewer/component-viewer.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,21 @@ export class ComponentViewer implements OnDestroy {
3535
public _componentPageTitle: ComponentPageTitle,
3636
public docItems: DocumentationItems,
3737
) {
38+
let params = [_route.params];
39+
if (_route.parent) {
40+
params.push(_route.parent.params);
41+
}
3842
// Listen to changes on the current route for the doc id (e.g. button/checkbox) and the
3943
// parent route for the section (material/cdk).
40-
combineLatest(_route.params, _route.parent.params).pipe(
44+
combineLatest(params).pipe(
4145
map((p: [Params, Params]) => ({id: p[0]['id'], section: p[1]['section']})),
4246
map(p => ({doc: docItems.getItemById(p.id, p.section), section: p.section}),
4347
takeUntil(this._destroyed))
4448
).subscribe(d => {
45-
this.componentDocItem = d.doc;
46-
if (this.componentDocItem) {
49+
if (d.doc !== undefined) {
50+
this.componentDocItem = d.doc;
4751
this._componentPageTitle.title = `${this.componentDocItem.name}`;
48-
this.componentDocItem.examples.length ?
52+
this.componentDocItem.examples && this.componentDocItem.examples.length ?
4953
this.sections.add('examples') :
5054
this.sections.delete('examples');
5155
} else {

src/app/pages/guide-viewer/guide-viewer.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<div class="docs-primary-header">
2-
<h1>{{guide.name}}</h1>
2+
<h1>{{guide?.name}}</h1>
33
</div>
44

55
<div class="docs-guide-wrapper">
66
<div class="docs-guide-toc-and-content">
7-
<doc-viewer class="docs-guide-content"
7+
<doc-viewer class="docs-guide-content"
88
(contentRendered)="toc.updateScrollPosition()"
9-
[documentUrl]="guide.document"></doc-viewer>
9+
[documentUrl]="guide?.document"></doc-viewer>
1010
<table-of-contents #toc container="guide-viewer"></table-of-contents>
1111
</div>
1212
</div>

src/app/pages/guide-viewer/guide-viewer.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import {DocsAppTestingModule} from '../../testing/testing-module';
77
const guideItemsId = 'getting-started';
88

99
const mockActivatedRoute = {
10-
fragment: Observable.create(observer => {
10+
fragment: new Observable(observer => {
1111
observer.complete();
1212
}),
13-
params: Observable.create(observer => {
13+
params: new Observable(observer => {
1414
observer.next({id: guideItemsId});
1515
observer.complete();
1616
})

src/app/pages/guide-viewer/guide-viewer.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ import {ComponentPageTitle} from '../page-title/page-title';
1212
styleUrls: ['./guide-viewer.scss'],
1313
})
1414
export class GuideViewer implements OnInit {
15-
guide: GuideItem;
15+
guide: GuideItem | undefined;
1616

1717
constructor(_route: ActivatedRoute,
1818
private _componentPageTitle: ComponentPageTitle,
1919
private router: Router,
2020
public guideItems: GuideItems) {
2121
_route.params.subscribe(p => {
22-
this.guide = guideItems.getItemById(p['id']);
22+
const guideItem = guideItems.getItemById(p['id']);
23+
if (guideItem) {
24+
this.guide = guideItem;
25+
}
2326

2427
if (!this.guide) {
2528
this.router.navigate(['/guides']);
@@ -28,7 +31,9 @@ export class GuideViewer implements OnInit {
2831
}
2932

3033
ngOnInit(): void {
31-
this._componentPageTitle.title = this.guide.name;
34+
if (this.guide !== undefined) {
35+
this._componentPageTitle.title = this.guide.name;
36+
}
3237
}
3338
}
3439

src/app/shared/copier/copier.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class CopierService {
5454
private removeFake() {
5555
if (this.textarea) {
5656
document.body.removeChild(this.textarea);
57-
this.textarea = null;
57+
delete this.textarea;
5858
}
5959
}
6060
}

src/app/shared/doc-viewer/doc-viewer.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class DocViewerTestComponent {
106106
documentUrl = 'http://material.angular.io/simple-doc.html';
107107
}
108108

109-
const FAKE_DOCS = {
109+
const FAKE_DOCS: {[key: string]: string} = {
110110
'http://material.angular.io/simple-doc.html': '<div>my docs page</div>',
111111
'http://material.angular.io/doc-with-example.html': `
112112
<div>Check out this example:</div>

src/app/shared/doc-viewer/doc-viewer.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ export class DocViewer implements OnDestroy {
107107
element, this._componentFactoryResolver, this._appRef, this._injector);
108108
let examplePortal = new ComponentPortal(componentClass, this._viewContainerRef);
109109
let exampleViewer = portalHost.attach(examplePortal);
110-
(exampleViewer.instance as ExampleViewer).example = example;
110+
if (example !== null) {
111+
(exampleViewer.instance as ExampleViewer).example = example;
112+
}
111113

112114
this._portalHosts.push(portalHost);
113115
});

src/app/shared/documentation-items/documentation-items.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,8 +543,9 @@ for (let category of DOCS[CDK]) {
543543
}
544544

545545
const ALL_COMPONENTS = DOCS[COMPONENTS].reduce(
546-
(result, category) => result.concat(category.items), []);
547-
const ALL_CDK = DOCS[CDK].reduce((result, cdk) => result.concat(cdk.items), []);
546+
(result: DocItem[], category: DocCategory) => result.concat(category.items), []);
547+
const ALL_CDK = DOCS[CDK].reduce(
548+
(result: DocItem[], cdk: DocCategory) => result.concat(cdk.items), []);
548549
const ALL_DOCS = ALL_COMPONENTS.concat(ALL_CDK);
549550
const ALL_CATEGORIES = DOCS[COMPONENTS].concat(DOCS[CDK]);
550551

@@ -564,12 +565,12 @@ export class DocumentationItems {
564565
return [];
565566
}
566567

567-
getItemById(id: string, section: string): DocItem {
568+
getItemById(id: string, section: string): DocItem | undefined {
568569
const sectionLookup = section == 'cdk' ? 'cdk' : 'material';
569570
return ALL_DOCS.find(doc => doc.id === id && doc.packageName == sectionLookup);
570571
}
571572

572-
getCategoryById(id: string): DocCategory {
573+
getCategoryById(id: string): DocCategory | undefined {
573574
return ALL_CATEGORIES.find(c => c.id == id);
574575
}
575576
}

src/app/shared/example-viewer/example-viewer.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ describe('ExampleViewer', () => {
175175
class TestExampleModule { }
176176

177177

178-
const FAKE_DOCS = {
178+
const FAKE_DOCS: {[key: string]: string} = {
179179
'/docs-content/examples-highlighted/autocomplete-overview-example-html.html':
180180
'<div>my docs page</div>',
181181
'/docs-content/examples-highlighted/autocomplete-overview-example-ts.html':

src/app/shared/guide-items/guide-items.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export class GuideItems {
6161
return GUIDES;
6262
}
6363

64-
getItemById(id: string): GuideItem {
64+
getItemById(id: string): GuideItem | undefined {
6565
return GUIDES.find(i => i.id === id);
6666
}
6767
}

src/app/shared/stackblitz/stackblitz-writer.spec.ts

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -64,45 +64,47 @@ describe('StackblitzWriter', () => {
6464
});
6565

6666
it('should open a new window with stackblitz url', fakeAsync(() => {
67-
let form;
68-
stackblitzWriter.constructStackblitzForm(data).then(result => form = result);
69-
flushMicrotasks();
70-
71-
for (const url of TEST_URLS) {
72-
http.expectOne(url).flush(FAKE_DOCS[url] || '');
73-
}
74-
flushMicrotasks();
75-
76-
expect(form.elements.length).toBe(15);
77-
78-
// Should have correct tags
79-
expect(form.elements[0].getAttribute('name')).toBe('tags[0]');
80-
expect(form.elements[0].getAttribute('value')).toBe('angular');
81-
expect(form.elements[1].getAttribute('name')).toBe('tags[1]');
82-
expect(form.elements[1].getAttribute('value')).toBe('material');
83-
expect(form.elements[2].getAttribute('name')).toBe('tags[2]');
84-
expect(form.elements[2].getAttribute('value')).toBe('example');
85-
86-
// Should bet set as private and have description and dependencies.
87-
expect(form.elements[3].getAttribute('name')).toBe('private');
88-
expect(form.elements[3].getAttribute('value')).toBe('true');
89-
expect(form.elements[4].getAttribute('name')).toBe('description');
90-
expect(form.elements[5].getAttribute('name')).toBe('dependencies');
91-
92-
// Should have files needed for example.
93-
expect(form.elements[6].getAttribute('name')).toBe('files[index.html]');
94-
expect(form.elements[7].getAttribute('name')).toBe('files[styles.css]');
95-
expect(form.elements[8].getAttribute('name')).toBe('files[polyfills.ts]');
96-
expect(form.elements[9].getAttribute('name')).toBe('files[.angular-cli.json]');
97-
expect(form.elements[10].getAttribute('name')).toBe('files[main.ts]');
98-
expect(form.elements[11].getAttribute('name')).toBe('files[material-module.ts]');
99-
expect(form.elements[12].getAttribute('name')).toBe('files[app/test.ts]');
100-
expect(form.elements[13].getAttribute('name')).toBe('files[app/test.html]');
101-
expect(form.elements[14].getAttribute('name')).toBe('files[app/src/detail.ts]');
67+
let form: HTMLFormElement;
68+
stackblitzWriter.constructStackblitzForm(data).then((result: HTMLFormElement) => {
69+
form = result;
70+
flushMicrotasks();
71+
72+
for (const url of TEST_URLS) {
73+
http.expectOne(url).flush(FAKE_DOCS[url] || '');
74+
}
75+
flushMicrotasks();
76+
77+
expect(form.elements.length).toBe(15);
78+
79+
// Should have correct tags
80+
expect(form.elements[0].getAttribute('name')).toBe('tags[0]');
81+
expect(form.elements[0].getAttribute('value')).toBe('angular');
82+
expect(form.elements[1].getAttribute('name')).toBe('tags[1]');
83+
expect(form.elements[1].getAttribute('value')).toBe('material');
84+
expect(form.elements[2].getAttribute('name')).toBe('tags[2]');
85+
expect(form.elements[2].getAttribute('value')).toBe('example');
86+
87+
// Should bet set as private and have description and dependencies.
88+
expect(form.elements[3].getAttribute('name')).toBe('private');
89+
expect(form.elements[3].getAttribute('value')).toBe('true');
90+
expect(form.elements[4].getAttribute('name')).toBe('description');
91+
expect(form.elements[5].getAttribute('name')).toBe('dependencies');
92+
93+
// Should have files needed for example.
94+
expect(form.elements[6].getAttribute('name')).toBe('files[index.html]');
95+
expect(form.elements[7].getAttribute('name')).toBe('files[styles.css]');
96+
expect(form.elements[8].getAttribute('name')).toBe('files[polyfills.ts]');
97+
expect(form.elements[9].getAttribute('name')).toBe('files[.angular-cli.json]');
98+
expect(form.elements[10].getAttribute('name')).toBe('files[main.ts]');
99+
expect(form.elements[11].getAttribute('name')).toBe('files[material-module.ts]');
100+
expect(form.elements[12].getAttribute('name')).toBe('files[app/test.ts]');
101+
expect(form.elements[13].getAttribute('name')).toBe('files[app/test.html]');
102+
expect(form.elements[14].getAttribute('name')).toBe('files[app/src/detail.ts]');
103+
});
102104
}));
103105
});
104106

105-
const FAKE_DOCS = {
107+
const FAKE_DOCS: {[key: string]: string} = {
106108
'/docs-content/examples-source/test.ts': 'ExampleComponent',
107109
'/docs-content/examples-source/test.html': `<example></example>`,
108110
'/docs-content/examples-source/src/detail.ts': 'DetailComponent',

src/app/shared/svg-viewer/svg-viewer.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {HttpClient} from '@angular/common/http';
22
import {Component, ElementRef, Input, NgModule, OnInit} from '@angular/core';
33

4-
54
@Component({
65
selector: 'docs-svg-viewer',
76
template: '<div class="docs-svg-viewer" aria-hidden="true"></div>',
@@ -16,7 +15,7 @@ export class SvgViewer implements OnInit {
1615
this.fetchAndInlineSvgContent(this.src);
1716
}
1817

19-
private inlineSvgContent(template) {
18+
private inlineSvgContent(template: string) {
2019
this.elementRef.nativeElement.innerHTML = template;
2120

2221
if (this.scaleToContainer) {

src/app/shared/table-of-contents/table-of-contents.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {TableOfContentsModule} from './table-of-contents.module';
66
import {DocsAppTestingModule} from '../../testing/testing-module';
77

88
const mockActivatedRoute = {
9-
fragment: Observable.create(observer => {
9+
fragment: new Observable(observer => {
1010
observer.complete();
1111
})
1212
};

src/app/shared/table-of-contents/table-of-contents.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import {Component, ElementRef, Inject, Input, OnInit} from '@angular/core';
1+
import {
2+
AfterViewInit, Component, ElementRef, Inject, Input, OnDestroy, OnInit
3+
} from '@angular/core';
24
import {DOCUMENT} from '@angular/common';
35
import {ActivatedRoute, NavigationEnd, Router} from '@angular/router';
46
import {Subject, fromEvent} from 'rxjs';
@@ -27,7 +29,7 @@ interface Link {
2729
styleUrls: ['./table-of-contents.scss'],
2830
templateUrl: './table-of-contents.html'
2931
})
30-
export class TableOfContents implements OnInit {
32+
export class TableOfContents implements OnInit, AfterViewInit, OnDestroy {
3133

3234
@Input() links: Link[] = [];
3335
@Input() container: string;
@@ -97,7 +99,7 @@ export class TableOfContents implements OnInit {
9799
}
98100

99101
/** Gets the scroll offset of the scroll container */
100-
private getScrollOffset(): number {
102+
private getScrollOffset(): number | void {
101103
const {top} = this._element.nativeElement.getBoundingClientRect();
102104
if (typeof this._scrollContainer.scrollTop !== 'undefined') {
103105
return this._scrollContainer.scrollTop + top;
@@ -107,7 +109,7 @@ export class TableOfContents implements OnInit {
107109
}
108110

109111
private createLinks(): Link[] {
110-
const links = [];
112+
const links: Array<Link> = [];
111113
const headers =
112114
Array.from(this._document.querySelectorAll(this.headerSelectors)) as HTMLElement[];
113115

src/app/shared/theme-picker/theme-picker.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
OnInit,
77
OnDestroy,
88
} from '@angular/core';
9-
import {StyleManager} from '../style-manager/style-manager';
9+
import {StyleManager} from '../style-manager';
1010
import {ThemeStorage, DocsSiteTheme} from './theme-storage/theme-storage';
1111
import {MatButtonModule} from '@angular/material/button';
1212
import {MatGridListModule} from '@angular/material/grid-list';
@@ -63,7 +63,10 @@ export class ThemePicker implements OnInit, OnDestroy {
6363
public styleManager: StyleManager,
6464
private _themeStorage: ThemeStorage,
6565
private _activatedRoute: ActivatedRoute) {
66-
this.installTheme(this._themeStorage.getStoredThemeName());
66+
const themeName = this._themeStorage.getStoredThemeName();
67+
if (themeName) {
68+
this.installTheme(themeName);
69+
}
6770
}
6871

6972
ngOnInit() {

src/tsconfig.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
"module": "es6",
99
"moduleResolution": "node",
1010
"outDir": "../dist/out-tsc",
11+
"noImplicitAny": true,
12+
"noImplicitReturns": true,
13+
"noImplicitThis": true,
14+
"noFallthroughCasesInSwitch": true,
15+
"strictNullChecks": true,
1116
"sourceMap": true,
1217
"target": "es5",
1318
"types": ["q", "selenium-webdriver", "jasmine"]

0 commit comments

Comments
 (0)