타입스크립트에서 선택적 속성은 속성 이름 뒤에 물음표(?)로 표시됩니다. 이는 속성이 객체에 존재할 수도 있고 존재하지 않을 수도 있음을 의미합니다. 이는 모든 필드가 필수는 아닌 구조를 설명할 때 편리합니다.
예:
interface User { id: number; name?: string; } const u1: User = { id: 1 }; // OK const u2: User = { id: 2, name: '이반' }; // OK
세부 사항:
undefined일 뿐만 아니라 객체에서 완전히 누락될 수도 있습니다.if (user.name))은 undefined와 누락된 것을 구분하지 못합니다.undefined일 수 있음을 고려하지 않고 체크 없이 메서드/속성에 접근하는 것입니다.이로부터 보호하기 위해:
undefined 체크를 사용하세요:if (user.name !== undefined) { console.log(user.name.toUpperCase()); }
console.log(user.name?.toUpperCase());
만약 객체가
{ foo?: string }인터페이스로 설명된다면, 항상foo속성이 문자열이나undefined일 수만 있나요? 예를 들어null값을 기록할 수 있나요?
잘못된 답변:
undefined일 수만 있으며 다른 것은 안 됩니다."올바른 답변:
null을 할당하면 타입스크립트는 이를 허용하지만, 오직 타입이 string | null로 확장된 경우에만 가능합니다. 기본적으로는 string이나 undefined뿐입니다.interface A { foo?: string } let x: A = { foo: null }; // 오류!
사례
대규모 프로젝트에서 일부 객체는 서버에서 선택적 필드가 없는 상태로 오곤 했습니다. 프로그래머는 이러한 속성에 직접 메서드를 호출(예: toLowerCase())하여 필드가 누락된 경우 런타임 오류를 유발하였습니다. 이 문제를 해결하기 위해 팀은 선택적 필드 접근에 대한 엄격한 검사 및 린터 규칙을 도입하였습니다.
사례
논리 표현식에서 속성의 존재와 참(true)을 혼동하여 if (user.email)이 비어 있는 문자열에 대해 작동하지 않았고, 이로 인해 일부 알림이 사용자에게 전송되지 않는 버그가 발생했습니다.
사례
팀은 선택적 속성에 null 값을 기록하기로 결정했으며, 이를 비정상적으로 생각했습니다. 타입스크립트는 오류를 발생시켰고, 이를 우회하기 위해 타입을 string | null로 확장해야 했으며, 이는 이러한 객체와 관련된 비즈니스 로직 전반을 재고해야 했습니다.