본문 바로가기
개발 공부/TypeScript

TypeScript - Keys, Type 지정하기

by 느림보어른 2021. 10. 23.

서문

업무 도중 TypeScript 파일에서 dictionary 형태를 가진 object 변수(ex: const dict = {ket : value, ...}를 사용해야 했다. 이때에 TS의 type을 어떻게 지정할 수 있는 지 알아보았다. 나는 단순한 형태 한 개만 있는 줄 알았지만 3가지 종류가 있기에 이들을 비교하고 정리하고자 기록을 남긴다.

Record<Keys, Type>

가장 일반적인 구조이다. Keys와 Type에서 각각 지정한 속성을 type으로 가지는 object를 생성한다. 또 이 유틸리티는 타입의 프로퍼티를 다른 타입에 매핑 시키는데 사용될 수 있다.(이 부분은 아직 잘 이해가 되지 않는다.)

interface CatInfo {
  age: number;
  breed: string;
}
 
type CatName = "miffy" | "boris" | "mordred";
 
const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};
 
cats.boris;

위의 예시를 분석하자면 cats의 property key값은 CatName으로 지정되어 3가지 값("miffy", "boris", "mordred")을 가질 수 있다. 그리고 key가 가리키는 property value의 값은 CatInfo로 지정되어 age의 경우 number, breed의 경우 string 값을 가진다.

Pick<Type, Keys>

이름에서 알 수 있듯이 property로 지정된 것들 중에서 뽑아서 사용할 수 있다. 여기서 Type은 property의 집합이고 Keys는 Type의 property의 key값이다.

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}
 
type TodoPreview = Pick<Todo, "title" | "completed">;
 
const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};
 
todo;

위의 예시를 분석하자면 ㅆodo는 3가지 property의 type을 지정하는 interface이다. 여기서 Pick을 사용해서 todo의 "title", "complited" property를 가진 새로운 type인 TodoPreview를 생성한다. 따라서 그 다음 생성한 todo는 TodoPreview로 type을 지정받았기에 2가지 속성("title", "completed")을 가지는 객체로 생성해야 한다.

 

좀 더 확실하게 알기 위해 위의 예시를 조금 변형해보면 다음과 같은 결과가 나타난다.

interface Todo {
    title: string;
    description: string;
    completed: boolean;
  }
   
  type TodoPreview = Pick<Todo, "title" | "completed">;
   
  const todo: TodoPreview = {
    title: "Clean room",
    description: true,
  };
   
  todo;

위의 코드는 첫번째 예시에서 todo의 property 중 completed를 description으로 변경했다. 물론 description의 값도 boolean에 맞게 true로 저장했다. 이 코드의 결과는 다음과 같은 에러가 발생한다.

C:\Users\KimDongHyeon\Desktop\testcode>tsc typescriptdoc.ts
typescriptdoc.ts:11:5 - error TS2322: Type '{ title: string; description: boolean; }' is not assignable to type 'TodoPreview'.
  Object literal may only specify known properties, and 'description' does not exist in type 'TodoPreview'.

11     description: true,
       ~~~~~~~~~~~~~~~~~


Found 1 error.

 위의 에러를 요약하자면 TodoPreview type에서는 description property가 없다고 말한다.

Omit<Type, Keys>

Omit은 Pick과는 반대이다. Keys로 지정한 property를 제외한 type을 생성한다.

interface Todo {
  title: string;
  description: string;
  completed: boolean;
  createdAt: number;
}
 
type TodoPreview = Omit<Todo, "description">;
 
const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
  createdAt: 1615544252770,
};
 
todo;
 
type TodoInfo = Omit<Todo, "completed" | "createdAt">;
 
const todoInfo: TodoInfo = {
  title: "Pick up kids",
  description: "Kindergarten closes at 5pm",
};
 
todoInfo;