프로그래밍프론트엔드 개발자

TypeScript의 선택적 체이닝 메커니즘(옵셔널 체이닝)은 어떻게 작동합니까? 어떤 문제를 해결하며, 실제로 사용할 때 어떤 경우에 오류를 유발할 수 있습니까?

Hintsage AI 어시스턴트로 면접 통과

응답.

선택적 체이닝(optional chaining)(?.)은 JavaScript에서 객체의 속성 및 메서드에 안전하게 접근할 수 있도록 도입되었습니다. TypeScript에서 특히 유용한데, 이는 undefined 또는 null인 속성이나 메서드에 접근하기 때문에 발생하는 실행 시간 오류를 피할 수 있도록 돕기 때문입니다.

질문의 배경

선택적 체이닝 이전에는 개발자들이 객체의 각 중첩 수준이 존재하는지 수동으로 확인해야 했습니다. 이로 인해 코드는 길어지고 읽기 어려워졌습니다:

if (obj && obj.a && obj.a.b) { // ... }

문제

정의되지 않은 객체에 중첩된 속성에 접근할 경우 실행 시간 오류가 발생할 수 있습니다: Cannot read property 'x' of undefined. 또한 긴 확인 체인은 코드의 유지 관리 및 가독성을 어렵게 만듭니다.

해결책

선택적 체이닝(?.)은 중첩된 속성, 메서드 또는 배열 요소에 접근할 수 있으며, 체인의 어느 부분이 null 또는 undefined인 경우 자동으로 undefined를 반환합니다.

코드 예:

interface User { name: string; address?: { city?: string; }; } const user: User = { name: 'Ivan' }; console.log(user.address?.city); // undefined

주요 특징:

  • 간결하고 안전하며 이해하기 쉬운 코드를 작성할 수 있습니다.
  • 속성, 메서드, 배열 인덱스에 대한 접근으로 작동합니다.
  • 반환 값의 타입은 T | undefined로, TypeScript 컴파일러가 이를 고려하여 오류를 방지합니다.

트릭 질문.

할당 연산자의 왼쪽에서 선택적 체이닝을 사용할 수 있습니까? 예: user.address?.city = 'Moscow'?

아니요, 선택적 체이닝은 할당 표현식의 왼쪽에서 사용할 수 없으며, 이는 컴파일 오류를 유발합니다. 선택적 체이닝은 읽기에서만 작동하고 쓰기에서는 작동하지 않습니다.

객체가 정의되지 않을 수 있는 경우 선택적 체이닝을 사용하여 메서드를 호출할 수 있습니까? 예: user?.logInfo()?

네, 메서드 호출 지점까지 객체가 undefined 또는 null일 수 있는 경우 user?.logInfo()를 호출하면 오류를 발생시키지 않고 user가 정의되지 않은 경우에는 단순히 undefined를 반환합니다.

user?.logInfo(); // user가 정의되면 logInfo가 호출되고, 그렇지 않으면 아무 일도 발생하지 않음

선택적 체이닝과 오래된 스타일의 '&&' 연산자(예: user && user.address && user.address.city)의 차이점은 무엇입니까?

선택적 체이닝은 더 짧고 모든 유형(메서드와 배열 포함)에서 작동하며, TypeScript는 타입 검사를 위해 이를 고려합니다. 중요한 점은 '&&' 연산자를 사용하는 경우 의도치 않게 true/false 또는 undefined가 아닌 중첩된 값을 얻을 수 있다는 것입니다. 선택적 체이닝은 항상 예상한 타입 또는 undefined를 보장하여 타입 출력에 반영됩니다.

일반적인 오류 및 안티 패턴

  • 선택적 체이닝이 할당 시 중첩된 객체를 "생성"한다고 기대하는 것 — 이는 사실이 아닙니다.
  • 절대로 undefined/null이 될 수 없는 변수에 접근할 때 선택적 체이닝을 사용하는 것(불필요하고 무의미한 코드).
  • 무의식적으로 선택적 체이닝을 모든 곳에 적용하는 습관이 있어, 이후 코드 유지가 어려워집니다.

실제 사례

부정적인 кей스

코드에서 비즈니스 로직상 항상 정의된 변수가 아닌데도 길고 복잡한 선택적 체이닝을 사용했습니다:

order?.customer?.address?.city = 'London';

장점:

  • 속성이 정의되지 않은 경우 발생할 수 있는 오류로부터 보호합니다.

단점:

  • 속성 중 하나라도 없으면 할당이 발생하지 않으며, 이로 인해 오류 처리 또는 알림이 없고 "숨겨진" 로직이 생깁니다; 코드가 복잡해집니다.

긍정적인 кей스

외부 데이터 작업 또는 실제로 값이 undefined일 수 있는 부분에서 선택적 체이닝을 사용합니다:

const city = apiResponse?.info?.location?.city || 'Unknown';

장점:

  • 예외를 발생시키지 않고도 불완전하거나 예상치 못한 변경을 포함한 객체들과 안전하게 작동합니다.
  • 읽기 쉽고 유지 보수가 쉬운 코드입니다.

단점:

  • 값이 없음에 대한 이유를 알고 싶다면 명시적인 오류 처리를 해야 합니다.