Angular 프로젝트에 TypeScript strict 모드 적용기

배경

회사 메인 프로젝트가 Angular 4에서 머물러 있었고, 최근 Angular 5로 업그레이드를 진행했다. 이참에 TypeScript도 2.7로 올리면서 strictNullChecks, noImplicitAny 등 strict 옵션을 활성화하기로 했다.

점진적 적용 전략

tsconfig.json에서 한번에 모든 strict 옵션을 켜면 수백 개의 에러가 발생했다. 팀 논의 끝에 단계적 접근을 택했다.

{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": false
  }
}

먼저 noImplicitAny만 활성화하고 모듈별로 수정했다. 가장 많이 발견된 패턴은 이벤트 핸들러였다.

// 기존
onSearch(event) {
  const value = event.target.value;
}

// 수정
onSearch(event: Event) {
  const target = event.target as HTMLInputElement;
  const value = target.value;
}

strictNullChecks 적용

2주 후 strictNullChecks를 켰다. 예상대로 옵셔널 체이닝이 없던 시절이라 null 체크 코드가 많이 추가됐다.

// 기존
getUserName(): string {
  return this.user.profile.name;
}

// 수정
getUserName(): string {
  if (!this.user || !this.user.profile) {
    return '';
  }
  return this.user.profile.name;
}

rxjsfilter 연산자로 null 제거 후 타입 가드를 활용하는 패턴도 많이 사용했다.

this.user$
  .pipe(
    filter(user => user !== null),
    map(user => user.name)
  )
  .subscribe(...);

결과

3주간의 작업으로 strict 모드 전환을 완료했다. 런타임 에러가 줄어들었고, 특히 undefined 참조 에러가 체감상 절반 이상 감소했다. 다만 보일러플레이트 코드가 늘어난 건 아쉬운 부분이다.