타입스크립트에서는 타입을 변환하는 것이 가능하다.
- 한 타입의 일부분을 새로운 타입으로 이용 가능
- 한 타입을 기본으로 하여 다른 타입으로 이용 가능
Index Type
: 특정 타입의 Index에 기반한 타입
객체의 value는 다음과 같이 접근 가능하다.
const obj = {
name: "yuna",
};
obj.name; // yuna
obj["name"]; // yuna
Animal이라는 타입을 선언한 뒤, 타입의 인덱스에 기반한 타입을 새로운 타입으로 사용할 수 있다.
type Animal = {
name: string;
age: number;
gender: "male" | "female";
};
type Name = Animal["name"]; //string
const text: Name = "rabbit";
type Gender = Animal["gender"]; // 'male' | 'female'
// 각 키를 타입으로 지정할 수 도 있다.
type Keys = keyof Animal; // 'name' | 'age' | 'gender'
const key : Keys = 'gender'
// 객체 타입을 선언할 때도 사용 가능하다.
type Person = {
name: string;
gender : Animal['gender']
}
const person = {
name : 'yuna',
gender: 'female', // 'male' | 'female' 중 하나의 값만 가능하다.
}
Mapped Type
: 기존의 타입들을 이용하면서 조금 다른 형태로 변환한 타입
다음과 같이 비효율적인 타입들이 있다..
type Video = {
title: string;
author:string;
}
// 선택 입력 video
type VideoOptional = {
title?: string;
author?: string;
description?: string;
}
// 읽기 전용 video
type VideoReadOnly = {
readonly title: string;
readonly author: string;
readonly description: string;
}
map type 적용
type 타입명<T> = {
[P in keyof T]: T[P] // for .. in과 동일, object key를 하나씩 돌아
}
위의 코드를 아래와 같이 개선할 수 있다.
=> Video 타입의 재사용성을 높임
type Video = {
title: string;
author:string;
}
type Optional<T> = {
[P in keyof T]?: T[P] // for .. in과 동일, object key를 하나씩 돌아
}
type ReadOnly<T> = {
readonly [P in keyof T]: T[P]
}
// Video 타입의 key를 빙글빙글 돌면서 물음표 붙여주기
type VideoOptional = Optional<Video>
// Video 타입의 key를 빙글빙글 돌면서 readonly 붙여주기
type VideoReadOnly = Optional<Video>
선언 하면서 동시에 사용하는 것도 가능하다.
type Animal = {
name: string;
age: number;
};
const animal: Optional<Animal> = {
// Animal type의 모든 프로퍼티를 가질 필요는 없음
name: "kitten",
};
type Proxy<T> = {
get(): T;
set(value: T): void;
};
type Proxify<T> = {
[P in keyof T]: Proxy<T[P]>;
};
Conditional Type
: 조건적으로 타입을 결정하는 타입
type Check<T> = T extends string ? boolean : number;
type Type = Check<string>; //boolean
삼항연산자로 표현한다.
type typeName<T> = T extends string
? "string"
: T extends number
? "number"
: T extends boolean
? "boolean"
: T extends undefined
? 'undefined'
: T extends Function
? "function"
: "object";
type T0 = typeName<string>; // string
type T1 = typeName<"str">; // string
type T2 = typeName<() => void>; // function
앞에서 살펴본 타입들은,
기존의 타입을 보장하고 유지하고 재사용하면서 다른 종류의 타입으로 변환한다!
사실 우리가 만들고 싶은 대부분의 타입은 이미 만들어져 있다. => Utility Type
ReadOnly
다음과 같은 상황이 발생했다고 하자.
type ToDo = {
title: string;
description : string;
}
// title을 보여주기만 하고 싶은데 변경해버리는,,,,그런,,상황
function display(todo: ToDo) {
todo.title = '타이틀 변경해버려,,,'
}
Readonly Type 사용하기
type ToDo = {
title: string;
description : string;
}
function display(todo: Readonly<ToDo>) {
todo.title = '타이틀 변경해버려,,,'
}
Readonly 타입을 command(Mac)를 누른채로 클릭하면 타입의 정의가 어떻게 되어있는지 볼 수 있다.
Partial Type
: 기존의 타입 중에서 부분적인 것만 허용하고 싶을 때
ex) 객체의 일부분 수정
type ToDo = {
title: string;
description: string;
label: string;
priority: "high" | "low";
};
function updateTodo(todo: ToDo, fieldsToUpdate: Partial<ToDo>): ToDo {
return { ...todo, ...fieldsToUpdate };
}
const todo: ToDo = {
title: "learn TypeScript",
description: "Study Hard",
label: "Study",
priority: "high",
};
const updated = updateTodo(todo, { priority: "low" });
console.log(updated)
Pick Type
: 기존의 타입에서 원하는 속성, 값만 골라서 하나의 타입으로서 사용하는 것
type Video = {
id: string;
title: string;
url: string;
data: string;
};
function getVideo(id: string): Video {
return {
id,
title: "video",
url: "https://..",
data: "byte-data..",
};
}
id, title만 가져오는 함수를 만들고 싶다면? => Pick Type을 사용한다.
// 재사용성을 위해 주로 따로 선언하여 사용한다.
type VideoMetaData = Pick<Video, 'id' | 'title'>
function getVideoMetaData(id: string): VideoMetaData {
return {
id,
title: 'title',
}
}
Omit Type
: Pick과 반대로 특정 타입에서 원하는 속성과 값을 뺀 새로운 타입을 만들 수 있음
type Video = {
id: string;
title: string;
url: string;
data: string;
};
// url과 data 키를 제외한 타입
type VideoMetaData = Omit<Video, 'url' | 'data'>
function getVideoMetaData(id: string): VideoMetaData {
return {
id,
title: 'title',
}
}
Record Type
: 두 가지 타입을 서로 엮을 수 있는 타입
ex) Page를 key로 PageInfo를 value로 엮어보기
type PageInfo = {
title: string;
};
type Page = "home" | "about" | "contact";
const nav: Record<Page, PageInfo> = {
home: { title: "Home" },
about: { title: "About" },
contact: { title: "Contact" },
};
'Web > TypeScript' 카테고리의 다른 글
[TypeScript] 타입스크립트 컴파일러 (0) | 2023.03.07 |
---|---|
[TypeScript] 제네릭 (Generics) (0) | 2023.03.01 |
[TypeScript] Composition (0) | 2023.02.25 |
[TypeScript] 객체지향 (OOP) (0) | 2023.02.24 |
[TypeScript] 기본 타입 #2 (0) | 2023.02.22 |
댓글