타입스크립트에서 옵셔널 프로퍼티를 다루는데요, 분명히 위에서 if로 존재 여부를 확인했는데 그 아래 콜백 안으로 들어가면 다시 undefined일 수 있다고 빨간 줄이 그어집니다.
function render(user?: User) {
if (user) {
items.forEach(item => {
console.log(user.name, item) // Object is possibly 'undefined'.
})
}
}바로 위 if에서 user가 truthy인 걸 확인했잖아요? 그런데 forEach 콜백 안에서는 user가 또 undefined일 수 있다고 하니 이해가 안 됩니다. if 블록 바로 안에서 user.name을 찍으면 에러가 안 나거든요. 콜백에 들어가는 순간만 이래요. 왜 이런 건가요?
댓글 1
핵심은 user가 재할당 가능한 변수(파라미터나 let)라는 점입니다. 재할당될 수 있으니 TS가 콜백 안에서의 값을 신뢰 못 하는 거죠. 그래서 가장 깔끔한 해결은 좁혀진 값을 const 지역변수로 한 번 복사하는 거예요.
if 안에서 const u = user 이렇게 잡아두고 콜백 안에서는 u.name을 쓰면 됩니다. u는 const라 절대 재할당이 안 되니, TS가 콜백 안에서도 좁힘(User 타입)을 그대로 유지해줍니다. 이 패턴이 제일 무난해요.
다른 방법으로는 콜백 안에서 user?.name처럼 옵셔널 체이닝을 쓰거나, 아예 함수를 (user: User) 형태로 받도록 초반에 가드하고 리턴해버리는(early return) 방식도 있습니다. 참고로 만약 user가 let이 아니라 처음부터 const였다면 이 문제 자체가 안 생겨요. 재할당 불가능한 변수는 콜백 안에서도 좁힘이 유지되거든요. 그래서 지역에선 되도록 const를 쓰는 습관이 이런 잔에러를 줄여줍니다.