문제의 역사:
in 연산자는 TypeScript가 JavaScript에서 유래했으며, 객체에 속성이 존재하는지 확인하는 데 널리 사용됩니다. TypeScript에서 이 연산자의 의미는 타입 시스템 덕분에 추가적인 의미를 갖게 되며, 특히 선택적 속성과 같은 경우에는 값의 존재뿐만 아니라 타입 수준에서의 선언이 중요합니다.
문제:
TypeScript에서 개발자들은 종종 undefined에 대한 간단한 검사와 객체에 속성이 존재하는지 검사를 혼동합니다. 속성이 존재하지만 그 값이 undefined이거나, 속성이 객체에 직접 정의되지 않고 상속된 경우 오류가 발생할 수 있습니다.
해결책:
in 연산자는 객체의 프로토타입 체인에 속성이 실제로 존재하는지 체크합니다. 이는 선택적 속성이나 계산된 속성을 검사할 때 중요한 역할을 하며, falsy 값의 예기치 않은 처리를 피할 수 있게 해줍니다:
코드 예시:
interface User { id: number; name?: string; } const user1: User = { id: 1 }; const user2: User = { id: 2, name: undefined }; console.log('name' in user1); // false console.log('name' in user2); // true
주요 특징:
in 연산자는 객체 또는 그 프로토타입에 속성이 존재하는지를 확인하며, 값이 존재하는지 여부와는 무관함undefined 검사(obj.prop !== undefined)와 in 사용의 차이는 무엇인가요?
undefined 검사는 값만 확인하고 속성이 존재하는지는 확인하지 않습니다. 속성이 존재하지만 undefined인 경우, 결과는 true가 됩니다. 속성이 아예 없는 경우, 그 값 또한 undefined지만 의미적으로는 다른 경우입니다.
예시:
const obj: any = { foo: undefined }; console.log('foo' in obj); // true console.log(obj.foo !== undefined); // false console.log('bar' in obj); // false console.log(obj.bar !== undefined); // false
in 연산자가 객체에서만 속성을 확인하고 프로토타입 체인은 무시할 수 있나요?
아니요, 표준 in은 프로토타입도 확인합니다. 자신의 속성만을 확인하려면 hasOwnProperty 메서드를 사용하세요:
const obj = Object.create({ foo: 123 }); obj.bar = 456; console.log('foo' in obj); // true console.log(obj.hasOwnProperty('foo')); // false
TypeScript에서 in 연산자를 사용하여 union 타입의 type narrowing을 수행할 수 있나요?
네, TypeScript에서 in은 분류된 유니온과 유사하며 타입을 특정 옵션으로 축소할 수 있게 해줍니다:
type Shape = { kind: 'circle'; radius: number } | { kind: 'square'; size: number }; function getArea(shape: Shape) { if ('radius' in shape) { // 여기서 shape은 원입니다 return Math.PI * shape.radius ** 2; } // 여기서 shape은 정사각형입니다 return shape.size ** 2; }
in 검사를 혼동하기in을 사용하기 (배열에서는 숫자 인덱스 및 상속된 속성에 대해 true를 반환함)in을 사용하려고 시도하기사용자 배열이 있는 프로젝트에서 user.name !== undefined로 선택적 필드를 검사하여 속성이 명시적으로 undefined인 사용자에 대해 잘못된 논리가 발생했습니다.
장점:
단점:
사용자 선택적 필드의 존재를 값과 관계없이 정확히 확인하기 위해 in을 사용하여 "필드 없음"과 "필드는 있지만 값은 지정되지 않음"을 올바르게 구분할 수 있었습니다.
장점:
단점:
in 연산자의 의미를 이해해야 하며, 이는 초보자에게 항상 명확하지 않을 수 있습니다.