프로그래밍백엔드 개발자

타입스크립트에서 심볼(TypeSymbol) 타입화 메커니즘이 어떻게 작동하나요? 객체의 키로서 심볼을 사용할 때 장점과 특징은 무엇이며, 타입스크립트로 API를 설계할 때 고려해야 할 세부사항은 무엇인가요?

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

답변.

문제의 역사:

심볼 타입은 JavaScript(ES6)에서 고유 식별자를 생성하기 위해 추가되었으며, 이는 객체의 다른 속성과 중복되지 않도록 보장합니다. 타입스크립트는 ES6 호환성을 지원하면서 심볼을 지원합니다.

문제:

심볼이 등장하기 전에는 객체 속성의 키로 문자열이 자주 사용되었습니다. 이는 객체의 확장 또는 재사용 시 우발적인 이름 충돌과 비공식 속성을 숨기는 것을 불가능하게 하여 오류를 유발했습니다. 심볼은 외부 코드에서 보이지 않는 고유한 키를 생성할 수 있도록 했지만, 타입화를 검토해야 하는 문제가 발생했습니다. 심볼 키를 가진 타입을 어떻게 설명하고 안전하게 API에서 사용할까요?

해결책:

타입스크립트는 값을 심볼로 지원하지만, 심볼 키의 타입화에는 몇 가지 특징이 있습니다. 심볼을 생성하기 위해서는 전역 생성자 또는 전역 심볼 레지스트리를 사용할 수 있습니다. 인터페이스나 타입에서 심볼 키는 명시적으로 심볼로 타입을 지정해야 하며, 이러한 속성에 접근하기 위해서는 심볼에 대한 참조를 유지해야 합니다.

코드 예:

const SECRET = Symbol('secret'); interface SecretObject { [SECRET]: string; visible: string; } const obj: SecretObject = { visible: 'see me', [SECRET]: 'hidden', }; console.log(obj.visible); // 'see me' // console.log(obj["secret"]); // 오류: 해당 속성이 없습니다! console.log(obj[SECRET]); // 'hidden'

주요 특징:

  • 심볼은 속성 키의 고유성을 보장하며 이는 문자열 키로는 불가능합니다.
  • 심볼 키를 가진 속성은 일반적인 순회(for...in, Object.keys)에서 표시되지 않습니다. 이는 숨겨진 속성에 유용합니다.
  • 모든 표준 작업(예: JSON.stringify)이 심볼 키를 고려하지 않으므로, 직렬화 및 역직렬화 시 중요합니다.

헷갈리는 질문.

심볼은 객체에서 사용될 때 문자열로 자동 변환될 수 있나요?

아니요, 심볼은 문자열로 자동 변환될 수 없으며, 이를 수행하려고 하면(TypeError) 오류가 발생합니다.

const mySymbol = Symbol('desc'); // alert('prefix_' + mySymbol); // TypeError

Object.keys로 심볼 키를 나열할 수 있나요?

아니요, Object.keys와 for...in은 심볼 키를 무시합니다. 그러한 키를 얻으려면 Object.getOwnPropertySymbols를 사용해야 합니다.

const sym = Symbol('a'); const obj = { [sym]: 42 }; Object.keys(obj); // [] Object.getOwnPropertySymbols(obj); // [Symbol(a)]

Object.assign으로 복사할 때 심볼 키의 속성이 전달되나요?

네, Object.assign는 문자열 키와 심볼 키를 모두 복사하지만, JSON.stringify는 그렇지 않습니다.

const s = Symbol('s'); const o1 = { [s]: 123, foo: 'bar' }; const o2 = Object.assign({}, o1); o2[s]; // 123

유형 오류 및 앤티 패턴

  • 여러 위치에서 심볼을 직접 생성(비공식적으로 재사용 가능한 Symbol(…))하는 것. 이는 서로 다른, 일치하지 않는 키를 초래합니다.
  • 심볼 키를 일반 문자열처럼 다루는 것은 접근 오류 및 속성 유실을 초래합니다.
  • JSON.stringify를 통해 심볼 키의 직렬화를 예상하는 것 — 이러한 속성은 유실됩니다.

실제 사례

부정적인 사례

개발자가 비공식 속성에 문자열 키('_private')를 사용하여 컨벤션에 의존했습니다. 팀 B에서 우연히 동일한 문자열을 추가하게 되었고, 속성이 덮어쓰여져 예측할 수 없는 오류가 발생했습니다.

장점:

  • 빠른 프로토타이핑.

단점:

  • 진정한 비공식성이 없음.
  • 이름 충돌 가능성.
  • 시스템 원간에 데이터 누수.

긍정적인 사례

두 번째 개발자는 숨겨진 속성을 위해 심볼을 적용했습니다(예: Symbol('internal')). 이제 팀 내부에서도 내부 데이터를 우연히 덮어쓰기 불가능하며, 특정 심볼에 대한 참조가 있어야만 접근 가능합니다.

장점:

  • 신뢰할 수 있는 비공식성.
  • 충돌 위험 최소화.

단점:

  • 새로운 직원에게 직관적이지 않은 인터페이스.
  • 숨겨진 필드를 디버깅하는 것이 더 어려워짐.