SHIN
TypeScript 실전 팁 10선
10편TypeScript를 쓰면서 strict: true를 빠뜨리면 절반만 쓰는 셈입니다. strict 모드가 어떤 검사를 활성화하는지, 왜 켜야 하는지 알아봅니다.
{
"compilerOptions": {
"strict": true
// 아래 7개를 한 번에 활성화합니다
// "strictNullChecks": true,
// "strictFunctionTypes": true,
// "strictBindCallApply": true,
// "strictPropertyInitialization": true,
// "noImplicitAny": true,
// "noImplicitThis": true,
// "alwaysStrict": true
}
}// strict 없이 — 런타임에 터짐
function getLength(s: string) {
return s.length // s가 null이면 TypeError
}
getLength(null) // 컴파일 통과 😱
// strict 켜면
function getLength(s: string) {
return s.length
}
getLength(null) // ❌ 컴파일 오류: null은 string에 할당 불가// strict 없이
function process(data) { // data는 암묵적으로 any
return data.toUpperCase() // 런타임에 터질 수 있음
}
// strict 켜면
function process(data: string) { // 타입 명시 강제
return data.toUpperCase()
}class UserService {
// strict 없이: 초기화 안 해도 통과
private db: Database
// strict 켜면: 반드시 초기화하거나 타입을 명확히 해야 함
private db!: Database // 단언 (외부에서 주입 보장 시)
private db: Database | null = null // 명시적 null 허용
constructor(db: Database) {
this.db = db // 생성자에서 초기화
}
}한 번에 strict를 켜면 오류가 수백 개 쏟아질 수 있습니다. 하나씩 켜는 방법을 권장합니다.
{
"compilerOptions": {
"noImplicitAny": true, // 1단계: any 제거
"strictNullChecks": true, // 2단계: null/undefined 처리
"strictFunctionTypes": true, // 3단계: 함수 타입 공변/반공변
"strict": true // 4단계: 나머지 전부
}
}{
"compilerOptions": {
"target": "ES2020",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
noUncheckedIndexedAccess는 strict에 포함되지 않지만, 배열/객체 인덱스 접근 시undefined가능성을 체크해줘서 함께 켜는 것을 권장합니다.
strict 모드는 처음엔 불편하지만, 런타임 오류를 컴파일 타임으로 끌어올려 디버깅 시간을 크게 줄여줍니다.