블로그 목록

TypeScript strict 플래그 — strict: true가 켜는 8가지

2026-06-256 min read
TypeScripttsconfigstrict타입 안전성

"strict": true 한 줄은 사실 8개의 플래그를 한꺼번에 켜는 묶음이다. 무엇이 켜지고, 각각 어떤 버그를 막는지 정리한다.

1. strict는 묶음이다

strict: true핵심 — 타입 안전의 두 축strictNullChecksnull/undefined 안전noImplicitAny암묵적 any 차단보조 — 함수 · 클래스 · this · catch 빈틈 보완strictFunctionTypesstrictPropertyInitializationstrictBindCallApplynoImplicitThisuseUnknownInCatchVariablesalwaysStrict

strict: true를 켜면 아래 8개가 모두 켜진다. 그중 타입 안전의 두 축은 strictNullChecks와 noImplicitAny이고, 나머지는 함수·클래스·this·catch의 빈틈을 메우는 보조 플래그다.

2. 핵심 ① strictNullChecks — null/undefined 안전

null·undefined를 모든 타입에서 분리해, "null일 수 있는 값"은 쓰기 전에 반드시 확인하게 강제한다.

let name: string = null; // ❌ null은 string에 할당 불가

let name2: string | null = null;
name2.toUpperCase();     // ❌ name2가 null일 수 있음
if (name2 !== null) {
  name2.toUpperCase();   // ✅ string으로 좁혀져 안전
}

→ 실무 런타임 버그의 큰 비중인 NPE(null 참조 에러) 를 컴파일 단계에서 잡는다. 가장 중요한 플래그.

3. 핵심 ② noImplicitAny — 암묵적 any 차단

타입을 명시 안 했는데 추론도 실패하면, 옛날엔 조용히 any가 됐다. 이걸 에러로 만든다.

function greet(name) {         // ❌ 'name'이 암묵적으로 any
  return "안녕 " + name;
}
function greet2(name: string) { // ✅
  return "안녕 " + name;
}

→ any가 코드에 퍼져 타입 검사를 무력화하는 걸 막는다. strictNullChecks 다음으로 중요.

4. strictFunctionTypes — 함수 매개변수 반공변 검사

함수 타입을 할당할 때 매개변수를 반공변으로 엄격히 검사한다.

let f: (x: Dog) => void;
let g: (x: Animal) => void;

f = g; // ✅ 넓은 걸 받는 함수를 대입
g = f; // ❌ 안전하지 않음 — 이 플래그가 잡음

단, 메서드 문법에는 적용되지 않고 함수 타입 표기에만 적용된다. (자세히는 공변과 반공변 글에서)

5. strictPropertyInitialization — 클래스 속성 초기화 강제

클래스 속성이 생성자에서 반드시 초기화되게 한다. (strictNullChecks도 켜져 있어야 동작)

class User {
  name: string; // ❌ 초기화 안 됨 → undefined 위험
  constructor() {}
}

class User2 {
  name = "";                       // 기본값
  name2!: string;                  // '!'로 "나중에 꼭 할당" 단언
  constructor(public name3: string) {} // 생성자 매개변수
}

6. strictBindCallApply — bind/call/apply 인자 검사

bind·call·apply로 호출할 때 인자 타입을 검사한다.

function add(a: number, b: number) { return a + b; }

add.call(null, 1, "2"); // ❌ "2"는 number가 아님
add.call(null, 1, 2);   // ✅

7. noImplicitThis — this의 암묵적 any 금지

this 타입을 추론할 수 없을 때 에러를 낸다.

function fn() {
  console.log(this.name); // ❌ 'this'가 암묵적 any
}
function fn2(this: { name: string }) {
  console.log(this.name); // ✅ this 타입 명시
}

8. useUnknownInCatchVariables — catch 변수를 unknown으로 (TS 4.4+)

catch의 에러 변수가 any가 아니라 unknown 이 된다. 쓰기 전에 좁히도록 강제한다.

try {
  /* ... */
} catch (e) {
  e.message; // ❌ e는 unknown
  if (e instanceof Error) {
    e.message; // ✅ 좁힌 뒤 사용
  }
}

9. alwaysStrict — JS 엄격 모드 강제

모든 파일을 자바스크립트 엄격 모드("use strict") 로 파싱하고 출력에도 넣는다. (TS의 strict가 아니라 JS 런타임의 strict mode)

10. 정리

플래그막는 것중요도
strictNullChecksnull/undefined 미처리 (NPE)⭐⭐⭐
noImplicitAny암묵적 any 확산⭐⭐⭐
strictFunctionTypes함수 매개변수 불안전 할당⭐⭐
strictPropertyInitialization클래스 속성 미초기화⭐⭐
strictBindCallApplybind/call/apply 인자 오류⭐
noImplicitThisthis의 암묵적 any⭐
useUnknownInCatchVariablescatch 에러 무검증 사용⭐
alwaysStrictJS 엄격 모드 강제⭐

11. 마이그레이션 팁

기존 JS 프로젝트를 옮길 때 strict를 한 번에 켜면 에러가 폭발한다. 그래서 보통 하나씩 켜며 점진적으로 잡는다.

// tsconfig.json — 점진 적용 예
{
  "compilerOptions": {
    "noImplicitAny": true,    // ① 먼저 any부터
    "strictNullChecks": true, // ② 그다음 null 안전
    // 안정화되면 최종적으로:
    // "strict": true
  }
}

noImplicitAny → strictNullChecks 순으로 닫고, 나머지는 strict: true로 한 번에 마무리하는 흐름이 무난하다.

한 줄 정리 — strict: true는 8개 플래그의 묶음이고, 그중 strictNullChecks(null 안전)와 noImplicitAny(any 차단) 가 타입 안전성의 두 축이다. 마이그레이션은 이 둘부터 점진적으로 켜는 게 정석이다.