노트

옵셔널 체이닝과 null 병합 연산자

Optional Chaining and Nullish Coalescing

프런트엔드#js · 연결된 개념 5개

쉽게 말하면

옵셔널 체이닝은 서랍 속 상자 속 물건을 꺼낼 때, 중간에 서랍이 없으면 에러를 내지 않고 '없음'이라고 답하는 연산자예요. ??는 정말 비어 있을 때만 기본값을 채워서 0이나 빈 문자열은 지켜 줘요.

비유가 깨지는 곳 '없음'으로 조용히 넘어가는 게 늘 좋은 건 아니에요. 원래 없으면 안 되는 값까지 ?.로 덮으면 버그가 숨으니, 경계에서 한 번 검사하고 안쪽은 확정된 타입으로 다루는 편이 나아요.

옵셔널 체이닝(Optional Chaining, ?.)은 앞의 값이 null이나 undefined이면 에러를 내지 않고 undefined를 돌려주는 접근 연산자다. null 병합 연산자(Nullish Coalescing Operator, ??)는 왼쪽이 null·undefined일 때만 오른쪽 기본값을 쓴다.

user?.job?.title            // job이 없으면 undefined (TypeError 아님)
user.greet?.()              // 메서드가 있을 때만 호출
 
const input = ''
input || 'DEFAULT'          // 'DEFAULT' — ''·0·false도 버린다
input ?? 'DEFAULT'          // ''       — null·undefined만 대체
  • ||는 falsy 값(0, '', false, NaN)을 모두 "없음"으로 본다. 0이나 빈 문자열이 정상 값인 폼 입력·설정값에서 버그가 난다. 이때 ??를 쓴다
  • ?.를 남발하면 "원래 없으면 안 되는 값"까지 조용히 넘어간다. 경계에서 한 번 검사하고 안쪽은 확정된 타입으로 다루는 편이 낫다(타입 좁히기와 타입 가드, 보호 구문)
  • TypeScript의 strictNullChecks를 켜면 어디에 이 연산자가 필요한지 컴파일러가 알려 준다(tsconfig 핵심 옵션)
  • null 대신 기본 동작을 가진 객체를 두는 설계는 특이 케이스와 널 객체

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 기본형 집착

    전화번호·금액·우선순위 같은 도메인 개념을 끝까지 문자열이나 숫자로만 다루는 냄새. 같은 검증과 포맷 코드가 여기저기 반복되고, 문자열로 모든 걸 표현하는 "stringly typed" 코드가 된다.

  • 함수 오버로드와 시그니처

    함수 오버로드(Function Overloads)는 구현 하나 위에 호출 방식별 시그니처를 여러 개 선언해, 인자 조합에 따라 정확한 반환 타입이 추론되게 하는 TypeScript 기능이다.

  • 매핑된 타입과 keyof

    매핑된 타입(Mapped Types)은 기존 타입의 키를 하나씩 돌며 새 타입을 만드는 문법([K in keyof T]: …)이다. keyof T는 객체 타입의 키 유니언을, T[K](인덱스 접근 타입, Indexed Access Type)는 그 키의 값 타입을 꺼낸다.

  • 타입 추론과 타입 검사

    타입 추론(Type Inference)은 표기가 없어도 컴파일러가 값의 타입을 정하는 단계이고, 타입 검사(Type Checking)는 정해진(추론됐거나 명시된) 타입을 코드가 지키는지 확인하는 단계다. 보통 추론이 먼저 일어나고, 그 결과를 기준으로 검사한다.

  • tsc --noEmit과 타입 검사 분리

    --noEmit은 tsc에게 타입 검사만 하고 JavaScript 파일은 만들지 말라고 하는 옵션이다. 오류가 있으면 0이 아닌 종료 코드로 실패하고, 없으면 조용히 끝난다.

보기 옵션