서문
업무 도중 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;