[TYPESCRIPT] 컴파일러 옵션 정리 — strict, noImplicitAny 등 꼭 알아야 할 핵심 옵션

TypeScript를 제대로 활용하기 위해서는 tsconfig.json의 컴파일러 옵션을 이해하는 것이 필수입니다. 특히 strict 모드와 관련된 옵션들은 코드 안정성, 개발 경험, 유지보수성을 크게 좌우합니다. 

 

strict 옵션 — 모든 타입 검사 강화

strict는 컴파일러의 가장 강력한 옵션으로, 여러 엄격 모드 옵션을 한 번에 켭니다.

{
  "compilerOptions": {
    "strict": true
  }
}

strict = true일 때 활성화되는 주요 옵션:

  • noImplicitAny
  • strictNullChecks
  • strictBindCallApply
  • strictFunctionTypes
  • strictPropertyInitialization
  • alwaysStrict
  • useUnknownInCatchVariables

Strict 모드를 사용하면 타입 안정성이 극적으로 높아지기 때문에 모든 실무 프로젝트에서 strict 사용을 강력히 권장합니다.

 

noImplicitAny — 암묵적인 any 금지

TypeScript에서 타입을 명시하지 않으면 자동으로 any가 되지만, 이는 타입 시스템의 장점을 무력화합니다. 이를 막는 옵션이 noImplicitAny입니다.

// noImplicitAny: true
function sum(a, b) {   // 오류: 'a', 'b'가 any로 추론
  return a + b;
}

자동으로 any가 되는 것을 막아 타입 명시를 강제하기 때문에 코드의 안전성이 크게 높아집니다.

 

strictNullChecks — null/undefined 안전성 확보

null과 undefined를 타입 시스템에서 엄격하게 다루도록 하는 옵션입니다.

let name: string = null; 
// strictNullChecks: true → 오류

이 옵션은 null 관련 런타임 오류를 대폭 줄이며, 현대 TypeScript 프로젝트에서는 사실상 필수입니다.

 

strictPropertyInitialization — 클래스 필드 초기화 검사

클래스의 필드가 생성자에서 반드시 초기화되었는지 검사합니다.

class User {
  name: string; // strictPropertyInitialization 오류

  constructor() {}
}

해결 방법은 두 가지입니다:

class User {
  name: string;

  constructor(name: string) {
    this.name = name; // ✔ OK
  }
}

혹은 “! 단언 연산자” 사용:

class User {
  name!: string; // ✔ 개발자가 책임지고 초기화한다고 선언
}

 

strictFunctionTypes — 함수 타입 검사 강화

함수의 매개변수 타입을 더 엄격하게 검사하여 안전하지 않은 함수 대입을 막아주는 옵션입니다.

type Fn = (value: string) => void;

let f: Fn;

let g = (value: string | number) => {}; 
// strictFunctionTypes → 대입 불가

콜백 기반 로직, 이벤트 핸들러 등에서 타입 안정성을 강화합니다.

 

strictBindCallApply — call/apply/bind 타입 검사 강화

자바스크립트의 call/apply/bind는 인자를 유연하게 받기 때문에 잘못된 인자가 전달돼도 오류가 발생하지 않는 문제가 있습니다.

function greet(name: string) {
  return `Hello ${name}`;
}

greet.call(null, 123); // strictBindCallApply: true → 오류

함수 인자 타입이 제대로 검사되기 때문에 안정적인 코드를 작성할 수 있습니다.

 

alwaysStrict — 항상 "use strict" 적용

컴파일된 JavaScript 파일에 항상 "use strict" 모드를 적용합니다.

{
  "compilerOptions": {
    "alwaysStrict": true
  }
}

use strict는 JavaScript의 다양한 안전 장치를 활성화하므로 TypeScript 프로젝트에서는 일반적으로 켜 두는 것을 권장합니다.

 

noImplicitThis — this 암시적 any 금지

this가 암시적으로 any로 되는 상황을 막는 옵션입니다.

function hello() {
  console.log(this.name); // this: any → 오류
}

특히 객체 메서드를 분리해서 호출할 때 발생하는 오류를 예방합니다.

 

noImplicitReturns — 반환값 누락 검사

함수에서 모든 코드 경로가 값을 반환해야 한다는 규칙을 검사합니다.

function getValue(x: number) {
  if (x > 0) return x;
  // noImplicitReturns 오류: 경로 중 return 없음
}

분기 처리에서 실수로 return을 빠뜨리는 오류를 막아줍니다.

 

useUnknownInCatchVariables — catch 변수의 기본 타입을 unknown으로

기존 catch 변수 타입은 any였습니다. 이 옵션이 true이면 자동으로 unknown이 되어 타입 안전성이 높아집니다.

try {
  throw new Error("fail");
} catch (e) {
  e.message; // unknown → Error 타입으로 narrowing 필요
}

예외 처리에서 타입 가드를 적용하도록 유도해 더 안전한 코드를 만들 수 있습니다.

 

실무에서 추천되는 tsconfig 설정

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictPropertyInitialization": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "useUnknownInCatchVariables": true
  }
}

위 설정은 대부분의 프로젝트에서 안정성과 생산성을 모두 만족시키는 구성입니다.

 


 

TypeScript의 컴파일러 옵션은 코드 품질과 안정성에 직접적인 영향을 미칩니다. 특히 strict 모드와 null/any 관련 옵션들은 실무에서 반드시 켜야 하며, 이를 통해 타입 시스템을 제대로 활용할 수 있습니다.

  • strict는 TypeScript의 핵심 안전 기능
  • noImplicitAny, strictNullChecks는 사실상 필수
  • strictFunctionTypes, strictBindCallApply는 함수 안정성 강화
  • noImplicitReturns, noImplicitThis는 유지보수성 증대