아이템 11. 잉여 속성 체크의 한계 인지하기

아이템 11. 잉여 속성 체크의 한계 인지하기

아이템 11. 잉여 속성 체크의 한계 인지하기 #

" 잉여 속성 체크를 이용하면 기본적으로 타입 시스템의 구조적 본질을 해치지 않으면서도 객체 리터럴에 알 수 없는 속성을 허용하지 않음으로써, 이번 아이템에서 다룰 Room이나 Options 예제 같은 문제점을 방지할 수 있습니다. (‘엄격한 객체 리터럴 체크’라고 불립니다.) “


(구조적 타이핑 기반에서) 타입이 명시된 변수에 ‘객체 리터럴’을 할당할 때, 추가로 설정된/할당된 속성(잉여 속성)이 있는지 체크할 수 있다.



객체 리터럴로 할당 시 적용된다. #

‘객체 리터럴’로 값을 할당하려고 하면, ‘잉여 속성 체크’에 의해 에러를 확인할 수 있다.

interface Room {
    numDoors: number;
    ceilingHeightFt: number;
}
const r: Room = {
    numDoors: 1,
    ceilingHeightFt: 10,
    elephant: 'present',
};
» tsc example.ts
example.ts:8:5 - error TS2322: Type '{ numDoors: number; ceilingHeightFt: number; elephant: string; }' is not assignable to type 'Room'.
  Object literal may only specify known properties, and 'elephant' does not exist in type 'Room'.

8     elephant: 'present',
      ~~~~~~~~~~~~~~~~~~~

단, 아래와 같이 ‘임시 변수’를 이용하는 경우에는 가능하다.

interface Room {
    numDoors: number;
    ceilingHeightFt: number;
}

const obj = {
    numDoors: 1,
    ceilingHeightFt: 10,
    elephant: 'present',
};

const r: Room = obj;

” obj 타입은 { numDoors: number; ceilingHeightFt: number; elephant: string } 으로 추론됩니다. obj 타입은 Room 타입의 부분 집합을 포함하므로, Room에 할당 가능하며 탕비 체커도 통과합니다. “


+ ‘잉여 속성 체크’는 ‘할당 가능 검사’와는 별도의 과정이라는 것을 인지해야 한다.


타입 단언문 사용 시에도 적용되지 않는다. #

interface Options {
    title: string;
    darkMode?: boolean;
}

const o = { darkmode: true, title: 'Ski Free' } as Options; // 정상



(잉여 속성 체크를 원치 않는다면) ‘인덱스 시그니처’를 사용해 추가 속성을 예상하도록 할 수 있다. #

interface Options {
    darkMode?: boolean;
    [otherOptions: string]: unknown;
}

const o1: Options = { darkMode:true, plusoption: true }; // 정상
const o2: Options = { plusoption: true }; // 정상

” 이런 방법이 데이터를 모델링하는 데 적절한지 아닌지에 대해서는 아이템 15에서 다룹니다. “



약한(weak) 타입에도 비슷한 체크가 동작한다. #

해당 내용은 다시 확인해볼 것



요약 #

  • ‘잉여 속성 체크’는 구조적 타이핑 시스템에서 허용되는 속성 이름의 오타와 같은 실수를 잡는 데 효과적이다.

    • 다만, 적용 범위가 매우 제한적이고 오직 객체 리터럴에만 적용된다는 특징이 있다.
  • ‘잉여 속성 체크’와 ‘일반 타입 체크’를 구분하여 인지해야 한다.

    • 타입 체커가 수행하는 ‘할당 가능 체크’와 다르다는 얘기이다.
  • ‘임시 변수’를 사용하면 ‘잉여 속성 체크’가 적용되지 않는다.