[TYPESCRIPT] null, undefined, strictNullChecks - TypeScript에서 결코 가볍게 보면 안 되는 개념

JavaScript 환경에서 개발하다 보면 nullundefined는 가장 자주 마주치며, 동시에 가장 많은 오류를 유발합니다. TypeScript는 이 문제를 해결하기 위해 strictNullChecks라는 강력한 옵션을 제공하며, 이를 활성화하느냐에 따라 타입 시스템의 동작 방식이 완전히 달라집니다.

 

null과 undefined의 차이

✔ undefined

JavaScript에서 값이 “할당되지 않은 상태”를 의미합니다.

let a;
console.log(a); // undefined

변수를 선언만 하고 초기화하지 않으면 자동으로 undefined가 됩니다.

✔ null

의도적으로 “값이 비어있음”을 나타낼 때 사용합니다.

let b = null;

즉, undefined는 시스템이 부여하고, null은 개발자가 명시적으로 할당하는 경우가 많습니다.

 

strictNullChecks 옵션이란?

TypeScript에서 가장 중요한 옵션 중 하나입니다. 이 옵션을 켜면 nullundefined가 모든 타입에서 자동으로 허용되지 않습니다.

// strictNullChecks: false (기본)
let name: string = null;       // 허용
let age: number = undefined;   // 허용

// strictNullChecks: true
let name: string = null;       // 오류
let age: number = undefined;   // 오류

즉, strictNullChecks는 “null 안전성”을 보장하기 위해 존재합니다. 이 옵션을 켠 순간 TypeScript는 더 이상 null과 undefined를 자동으로 허용하지 않습니다.

 

strictNullChecks가 켜졌을 때의 동작

1. null/undefined를 허용하려면 명시적으로 타입에 포함해야 함

let username: string | null = null;
let email: string | undefined = undefined;

이는 “nullable한 값”임을 타입 정의에서 명확하게 알리는 패턴입니다.

2. 값 사용 전 반드시 null 체크 필요

function printLength(str: string | null) {
  if (str !== null) {
    console.log(str.length);
  }
}

이제 TypeScript가 null 가능성을 인지하기 때문에 런타임 오류를 크게 줄일 수 있습니다.

 

Non-null Assertion Operator ( ! )

“이 값은 절대 null이 아니다”라는 뜻으로 null 가능성 체크를 무시하는 연산자입니다.

let el = document.getElementById("app")!;
el.innerHTML = "Hello";

하지만 남용은 매우 위험합니다. strictNullChecks를 켠 의미가 사라질 수 있기 때문에 정말 확실할 때만 사용해야 합니다.

 

Optional Chaining (?.)

null/undefined가 발생할 가능성이 있는 값을 안전하게 접근할 수 있는 문법입니다.

user?.profile?.email

이 문법은 null-safe 코드를 작성할 때 필수입니다.

 

Nullish Coalescing (??)

null 또는 undefined일 때만 기본값을 사용하도록 도와줍니다.

let nickname = input ?? "Guest";

빈 문자열("")이나 0은 그대로 유지되기 때문에 기존의 || 연산자보다 더 안전합니다.

 

strictNullChecks를 반드시 켜야 하는 이유

  • 런타임 오류의 80%가 null/undefined 관련 오류
  • null 가능성을 타입에서 명확하게 표현할 수 있음
  • 도구(IDE, LSP)가 null-safe 코드를 자동으로 유도
  • 함수 호출 과정에서 값이 누락되는 버그 방지
  • 대규모 프로젝트에서 유지보수성 급증

strictNullChecks는 타입 안정성을 극대화하는 가장 중요한 옵션이며 최근 모든 현대 TypeScript 프로젝트에서는 거의 “필수”로 간주됩니다.

 

실무에서 자주 쓰는 nullable 설계 패턴

✔ 명시적인 nullable 타입

type Nullable<T> = T | null;

✔ API 응답 패턴

type UserResponse = {
  id: number;
  name: string | null; 
};

✔ optional property (undefined 가능성 포함)

type User = {
  name?: string; // string | undefined
};

옵셔널 속성은 자동으로 undefined 가능성을 포함합니다.

 


 

null과 undefined는 JavaScript에서 매우 흔하면서도 위험한 값이지만, TypeScript의 strictNullChecks 옵션을 통해 안전한 코딩을 강제할 수 있습니다.

  • null = 의도적으로 비워짐
  • undefined = 초기화되지 않음
  • strictNullChecks = null/undefined를 타입 시스템에서 엄격하게 다룸
  • nullable 값은 반드시 타입으로 명시
  • optional chaining, nullish coalescing로 안전하게 접근 가능