이전 글: 2019/12/27 - [Typescript] - 더 나은 타입스크립트 작성하기 1 - Skills
1편에 이어 2편이다. 역시나 타입스크립트 작성 스킬 부분을 이야기하려고 한다.
아래와 같은 예제가 있고, 여기에 타입 지정을 하고 싶다면 어떻게 해야 할까?
const obj1 = {
name: "jacob",
address: "seoul",
hobby: "coding"
};
const obj2 = {
name: "jacob",
address: "seoul",
hobby: "coding",
age: 29
};
여기서 전제는 obj1은 항상 name, address, hobby라는 프러퍼티만 갖고, obj2는 name, address, hobby, age라는 프러퍼티만 갖는다고 하자.
1 - Index Signature
첫번째 방법으로는 Index Signature를 생각할 수 있다.
type Obj = { [property: string]: string };
가장 넓게 타입을 지정한다면 이렇게 할 수 있다. 하지만 이렇게 지정하면, obj2에는 적용하지 못하고(number 타입이 존재하므로), 또한 obj1에 다른 프로퍼티가 타입만 맞는다면 무한정 추가될 수 있다. 물론 제네릭을 사용해서 위 코드를 좀 더 개선할 수 있다.
interface Obj<T, K> {
[property: string]: T | K;
}
const obj1: Obj<string, number> = {
name: "jacob",
address: "seoul",
hobby: "coding"
};
const obj2: Obj<string, number> = {
name: "jacob",
address: "seoul",
hobby: "coding",
age: 29
};
하지만 여전히 프로퍼티를 추가할 수가 있다. 무엇인가 프로퍼티를 제한할 수 있는 것이 필요하다.
2 - Record<K, T>
두 번째 방법은 타입스크립트에서 제공하는 Record를 이용하는 것이다. Record<K, T>는 T 타입의 K 프로퍼티 집합을 만드는 것이다.
// Record<K, T> 예제
interface PageInfo {
title: string;
}
type Page = 'home' | 'about' | 'contact';
const x: Record<Page, PageInfo> = {
about: { title: 'about' },
contact: { title: 'contact' },
home: { title: 'home' },
};
Record를 사용하면 아래와 같이 정의할 수 있다.
type Obj1 = Record<"name" | "address" | "hobby" , string>;
type Obj2 = Record<"name" | "address" | "hobby" | "age", string | number>;
const obj1: Obj1 = {
name: "jacob",
address: "seoul",
hobby: "coding"
};
const obj2: Obj2 = {
name: "jacob",
address: "seoul",
hobby: "coding",
age: 29
};
이제 프로퍼티의 타입을 명확하게 지정할 수 있게 되었다.
3 - mapped type
마지막 방법은 mapped type을 이용하는 것이다. 여기에 대한 개념은 이미 전 글에서 다뤘으니 생략한다.
type Obj1 = {
[k in "name" | "address" | "hobby"]: string;
};
type Obj2 = {
[k in "name" | "address" | "hobby" | "age"]: k extends 'age' ? number : string;
};
const obj1: Obj1 = {
name: "jacob",
address: "seoul",
hobby: "coding"
};
const obj2: Obj2 = {
name: "jacob",
address: "seoul",
hobby: "coding",
age: 29
};
본인이 사용하는 프로젝트에 맞게 가능한 타입을 타이트하게 설정해 줘야지 타입 안정성이 확보될 수 있다는 점을 명심하자!
'Typescript' 카테고리의 다른 글
enum 대신 object를 generic을 이용하여 union type으로 변경하기 (1) | 2021.03.20 |
---|---|
더 나은 타입스크립트 작성하기 3 - readonly (1) | 2020.01.01 |
타입스크립트 - 배열의 값을 타입(union)으로 바꾸기(const assertions) (0) | 2019.12.31 |
더 나은 타입스크립트 작성하기 1 - Skills (0) | 2019.12.27 |
[Typescript] 타입 시스템 (0) | 2019.12.21 |