Typescript 잉여 속성 체크의 한계

이재철·2022년 3월 19일
0

TypeScript

목록 보기
5/11
post-thumbnail

타입이 명시된 변수에 객체 리터럴을 할당할 때 ts는 해당 타입의 속성이 있는지, 그리고 그 외의 속성은 없는지 확인합니다

  • 잉여 속성체크
interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}
const r: Room = {
  numDoors: 1,
  ceilingHeightFt: 10,
  elephant: "present",
  // ~~~~~~~~~~~~~~~~~~ Object literal may only specify known properties,
  //                    and 'elephant' does not exist in type 'Room'
};

임시 변수를 도입해서 테스트
obj 타입은 Room 타입의 부분 집합을 포함하므로, Room에 할당 가능하며 타입 체커도 통과함

interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}
const obj = {
  numDoors: 1,
  ceilingHeightFt: 10,
  elephant: 'present',
};
const r: Room = obj;  // OK

ts는 단순히 런타임에 예외를 던지는 코드에 오류를 표시하는 것뿐 아니라, 의도와 다르게 작성된 코드까지 찾으려고함

interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}
function setDarkMode() {}
interface Options {
  title: string;
  darkMode?: boolean;
}
function createWindow(options: Options) {
  if (options.darkMode) {
    setDarkMode();
  }
  // ...
}
createWindow({
  title: 'Spider Solitaire',
  darkmode: true
// ~~~~~~~~~~~~~ Object literal may only specify known properties, but
//               'darkmode' does not exist in type 'Options'.
//               Did you mean to write 'darkMode'?
// darkmode가 아닌 darkMode로 사용해야됨
});

Options 타입의 범위가 매우 넓기 때문에, 순수한 구조적 타입 체커는 이런 종류의 오류를 찾아내지 못함
darkMode 속성에 boolean 타입이 아닌 다른 타입의 값이 지정된 경우를 제외하면, string 타입인 title 속성과 또 다른 어떤 속성을 가지는 모든 객체는 Options 타입의 범위에 속함

interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}
function setDarkMode() {}
interface Options {
  title: string;
  darkMode?: boolean;
}
const o1: Options = document;  // OK
const o2: Options = new HTMLAnchorElement;  // OK

단언문보다 선언문을 사용해야 하는 단적인 이유

interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}
function setDarkMode() {}
interface Options {
  title: string;
  darkMode?: boolean;
}
const o: Options = { darkmode: true, title: 'Ski Free' };
                  // ~~~~~~~~ 'darkmode' does not exist in type 'Options'...

// 타입 구분 없는 임시 변수 
const intermediate = { darkmode: true, title: 'Ski Free' }; // 객체 리터럴
// 객체 리터럴이 아님
const o: Options = intermediate;  // OK
// 타입 단언문 사용
const o = { darkmode: true, title: 'Ski Free' } as Options;  // OK

선택적 속성만 가지는 '약한(week)타입' 에도 비슷한 체크가 동작

interface LineChartOptions {
  logscale?: boolean;
  invertedYAxis?: boolean;
  areaChart?: boolean;
}
const opts = { logScale: true };
const o: LineChartOptions = opts;
   // ~ Type '{ logScale: boolean; }' has no properties in common
   //   with type 'LineChartOptions'
profile
혼신의 힘을 다하다 🤷‍♂️

0개의 댓글