diff options
author | crupest <crupest@outlook.com> | 2019-03-11 21:01:28 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2019-03-11 21:01:28 +0800 |
commit | 4f7eba96dfdcd831c7a40dee035b8871df8d452b (patch) | |
tree | fa18c63d9530364b557066ffcb703c927b17213f /Timeline | |
parent | 8caef17dd3e455de27f44d13751c27ee4dfe2e1e (diff) | |
download | timeline-4f7eba96dfdcd831c7a40dee035b8871df8d452b.tar.gz timeline-4f7eba96dfdcd831c7a40dee035b8871df8d452b.tar.bz2 timeline-4f7eba96dfdcd831c7a40dee035b8871df8d452b.zip |
Use strict check of typescript compiler.
Diffstat (limited to 'Timeline')
11 files changed, 48 insertions, 22 deletions
diff --git a/Timeline/ClientApp/src/app/todo/todo-item/todo-item.component.ts b/Timeline/ClientApp/src/app/todo/todo-item/todo-item.component.ts index 2ea6997a..50829769 100644 --- a/Timeline/ClientApp/src/app/todo/todo-item/todo-item.component.ts +++ b/Timeline/ClientApp/src/app/todo/todo-item/todo-item.component.ts @@ -1,13 +1,18 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; + import { TodoItem } from '../todo-item'; +import { throwIfFalsy } from 'src/app/utilities/language-untilities'; @Component({ selector: 'app-todo-item', templateUrl: './todo-item.component.html', styleUrls: ['./todo-item.component.css', '../todo-list-color-block.css'] }) -export class TodoItemComponent { +export class TodoItemComponent implements OnInit { - @Input() item: TodoItem; + @Input() item: TodoItem | undefined; + ngOnInit() { + throwIfFalsy(this.item, 'item'); + } } diff --git a/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.spec.ts b/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.spec.ts index 4db28768..613a8fa6 100644 --- a/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.spec.ts +++ b/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.spec.ts @@ -49,7 +49,7 @@ describe('InternalUserService', () => { const httpController = TestBed.get(HttpTestingController) as HttpTestingController; httpController.expectOne((request: HttpRequest<CreateTokenRequest>) => - request.url === createTokenUrl && + request.url === createTokenUrl && request.body !== null && request.body.username === 'user' && request.body.password === 'user').flush(<CreateTokenResponse>{ token: 'test-token', @@ -73,7 +73,7 @@ describe('InternalUserService', () => { const mockToken = 'mock-token'; const tokenValidateRequestMatcher = (req: HttpRequest<ValidateTokenRequest>) => { - return req.url === validateTokenUrl && req.body.token === mockToken; + return req.url === validateTokenUrl && req.body !== null && req.body.token === mockToken; }; beforeEach(() => { diff --git a/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.ts b/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.ts index 91a67e5b..4767bd16 100644 --- a/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.ts +++ b/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.ts @@ -5,6 +5,8 @@ import { Router } from '@angular/router'; import { Observable, of, throwError, BehaviorSubject } from 'rxjs'; import { map, catchError, retry } from 'rxjs/operators'; +import { nullIfUndefined } from '../../utilities/language-untilities'; + import { AlreadyLoginError, BadCredentialsError, BadNetworkError, UnknownError } from './errors'; import { createTokenUrl, validateTokenUrl, CreateTokenRequest, @@ -23,7 +25,7 @@ export type UserLoginState = 'nologin' | 'invalidlogin' | 'success'; }) export class InternalUserService { - private token: string; + private token: string | null = null; private userInfoSubject = new BehaviorSubject<UserInfo | null>(null); get currentUserInfo(): UserInfo | null { @@ -36,7 +38,7 @@ export class InternalUserService { constructor(private httpClient: HttpClient, private router: Router) { } - userRouteNavigate(commands: any[]) { + userRouteNavigate(commands: any[] | null) { this.router.navigate([{ outlets: { user: commands @@ -57,7 +59,7 @@ export class InternalUserService { }), map(result => { if (result.isValid) { - this.userInfoSubject.next(result.userInfo); + this.userInfoSubject.next(nullIfUndefined(result.userInfo)); return <UserLoginState>'success'; } else { this.token = null; diff --git a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts index 498ffaa1..cf5f3643 100644 --- a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts +++ b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts @@ -11,15 +11,16 @@ export class UserDialogComponent implements OnInit, OnDestroy { constructor(private userService: InternalUserService, private router: Router) { } - @ViewChild(RouterOutlet) outlet: RouterOutlet; + @ViewChild(RouterOutlet) outlet!: RouterOutlet; isLoading = true; ngOnInit() { // this is a workaround for a bug. see https://github.com/angular/angular/issues/20694 - this.router.events.subscribe(e => { + const subscription = this.router.events.subscribe(e => { if (e instanceof ActivationStart && e.snapshot.outlet === 'user') { this.outlet.deactivate(); + subscription.unsubscribe(); } }); diff --git a/Timeline/ClientApp/src/app/user/user-login-success/user-login-success.component.ts b/Timeline/ClientApp/src/app/user/user-login-success/user-login-success.component.ts index 48e331d6..1369d17d 100644 --- a/Timeline/ClientApp/src/app/user/user-login-success/user-login-success.component.ts +++ b/Timeline/ClientApp/src/app/user/user-login-success/user-login-success.component.ts @@ -3,6 +3,7 @@ import { ActivatedRoute } from '@angular/router'; import { UserInfo } from '../entities'; import { InternalUserService } from '../internal-user-service/internal-user.service'; +import { throwIfFalsy } from 'src/app/utilities/language-untilities'; @Component({ selector: 'app-user-login-success', @@ -13,12 +14,18 @@ export class UserLoginSuccessComponent implements OnInit { displayLoginSuccessMessage = false; - userInfo: UserInfo; + userInfo: UserInfo | undefined; constructor(private route: ActivatedRoute, private userService: InternalUserService) { } ngOnInit() { - this.userInfo = this.userService.currentUserInfo; + const { currentUserInfo } = this.userService; + + if (!currentUserInfo) { + throw new Error('Route error. No login now!'); + } + + this.userInfo = this.userService.currentUserInfo!; this.displayLoginSuccessMessage = this.route.snapshot.paramMap.get('reason') === 'login'; } } diff --git a/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts b/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts index 79a788de..3505d50b 100644 --- a/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts +++ b/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts @@ -4,7 +4,7 @@ import { ActivatedRoute } from '@angular/router'; import { InternalUserService } from '../internal-user-service/internal-user.service'; -export type LoginMessage = 'nologin' | 'invalidlogin' | string; +export type LoginMessage = 'nologin' | 'invalidlogin' | string | null | undefined; @Component({ diff --git a/Timeline/ClientApp/src/app/utilities/debounce-click.directive.spec.ts b/Timeline/ClientApp/src/app/utilities/debounce-click.directive.spec.ts index 75710d0c..89f66b99 100644 --- a/Timeline/ClientApp/src/app/utilities/debounce-click.directive.spec.ts +++ b/Timeline/ClientApp/src/app/utilities/debounce-click.directive.spec.ts @@ -13,8 +13,8 @@ interface TestComponent { template: '<button (appDebounceClick)="clickHandler()"></button>' }) class DefaultDebounceTimeTestComponent { - @ViewChild(DebounceClickDirective) - directive: DebounceClickDirective; + + @ViewChild(DebounceClickDirective) directive!: DebounceClickDirective; clickHandler: () => void = () => { }; } @@ -24,10 +24,9 @@ class DefaultDebounceTimeTestComponent { template: '<button (appDebounceClick)="clickHandler()" [appDebounceClickTime]="debounceTime"></button>' }) class CustomDebounceTimeTestComponent { - debounceTime: number; + debounceTime: number | undefined; - @ViewChild(DebounceClickDirective) - directive: DebounceClickDirective; + @ViewChild(DebounceClickDirective) directive!: DebounceClickDirective; clickHandler: () => void = () => { }; } diff --git a/Timeline/ClientApp/src/app/utilities/debounce-click.directive.ts b/Timeline/ClientApp/src/app/utilities/debounce-click.directive.ts index feb0404e..1d01b671 100644 --- a/Timeline/ClientApp/src/app/utilities/debounce-click.directive.ts +++ b/Timeline/ClientApp/src/app/utilities/debounce-click.directive.ts @@ -7,7 +7,7 @@ import { debounceTime } from 'rxjs/operators'; }) export class DebounceClickDirective implements OnInit, OnDestroy { - private subscription: Subscription; + private subscription: Subscription | undefined; @Output('appDebounceClick') clickEvent = new EventEmitter<any>(); @@ -34,6 +34,8 @@ export class DebounceClickDirective implements OnInit, OnDestroy { } ngOnDestroy() { - this.subscription.unsubscribe(); + if (this.subscription) { + this.subscription.unsubscribe(); + } } } diff --git a/Timeline/ClientApp/src/app/utilities/language-untilities.ts b/Timeline/ClientApp/src/app/utilities/language-untilities.ts new file mode 100644 index 00000000..f898039a --- /dev/null +++ b/Timeline/ClientApp/src/app/utilities/language-untilities.ts @@ -0,0 +1,9 @@ +export function nullIfUndefined<T>(value: T | undefined): T | null { + return value === undefined ? null : value; +} + +export function throwIfFalsy(value: any, name: string = '<unknown name>') { + if (!value) { + throw new Error(name + ' is falsy.'); + } +} diff --git a/Timeline/ClientApp/tsconfig.json b/Timeline/ClientApp/tsconfig.json index ef44e286..437067d6 100644 --- a/Timeline/ClientApp/tsconfig.json +++ b/Timeline/ClientApp/tsconfig.json @@ -15,6 +15,7 @@ "lib": [ "es2017", "dom" - ] + ], + "strict": true } } diff --git a/Timeline/ClientApp/tslint.json b/Timeline/ClientApp/tslint.json index 3ea984c7..dcc5f765 100644 --- a/Timeline/ClientApp/tslint.json +++ b/Timeline/ClientApp/tslint.json @@ -64,7 +64,7 @@ "ignore-params" ], "no-misused-new": true, - "no-non-null-assertion": true, + "no-non-null-assertion": false, "no-shadowed-variable": true, "no-string-literal": false, "no-string-throw": true, |