타입스크립트의 다양한 Utility Type에 대해서 알아보자.
Index Type와 Mapped Typ, Conditional Type, Read only , partial Type, Pick Type , Omit Type
인덱스 타입을 이용하면 다른 타입의 키에 접근에 그에 해당하는 value의 타입을 그대로 활용할 수 있다.
//아래와 같이 animal 타입을 정해줬다고 하자.
type Animal = {
name: string;
age: number;
gender: "male" | "female";
};
type Name = Animal["name"]; // Animal의 key의 타입인 string
type Gender = Animal["gender"]; //'male' | 'female' Gender의 value인 Union Type
type Keys = keyof Animal; // 'name' | 'age' | 'gender' Animal 타입의 keys로 Keys 의 3가지가 union Type 타입으로 할당
const key: Keys = "gender";
type Person = {
name: string;
gender: Animal["gender"]; // 'male' | 'female' 할당
};
const person: Person = {
name: "No war",
gender: "male", // 'male | 'female' 아닐시 에러
};
}
// 아래와 같은 비디오 타입이 있다고 가정하자.
type Video = {
title: string;
author: string;
};
// 위에서 선언한 타입을 optional한 타입을 주고 싶다면,
type VideoOptional = {
title?: string;
author?: string;
};
// 위와 같이 활용이 가능하다 하지만, Video 타입에서 후에 description이 할당된다면 두 가지 타입 둘다 바꿔줘야 하는 번거로움이 생긴다.
//이렇듯 재사용성을 위해서는 아래와 같이 mapped Type이 활용가능하다
Solution
// Mapped Type ?
// JS에 Map 함수를 보면 key를 순회해서 그에 해당하는 콜백함수를 돌려서 새로운 배열을 반환하는 것처럼 혹은 for...in 구문 처럼 각 key를 순회하는 원리랑 비슷하다고 볼 수 있다.
type Optional<T> = {
[P in keyof T]?: T[P]; // for...in 과 비슷
};
type VideoOptional = Optional<video>; // 이처럼 간단하게 사용가능!
//or 활용 -> 유틸리티엔 NotNullable 함수 구현되있음!
type Nullable<T> = { [P in keyof T]: T[P] | null }; // 이 타입은 null이 들어가거나 혹은 기본의 정해준 t[p]의 value가 들어감
const vidoeObj: Nullable<Video> = {
title:"stop war",
autho:null,
}
type Check<T> = T extends string ? boolean : number; // string을 상속해서 확장하면 bool 아니면 number라고 지정이 가능
type Type = Check<string>; // boolean
type Type2 = Check<number>; // number
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
("string");
type T1 = TypeName<"a">; // string "a"는 문자열이니 문자열을 상속하기 때문에 string;
("string");
type T2 = TypeName<() => void>; //function
("function");
/**
* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
// Todo라는 타입이 있고 update는 말그대로 todo 할일을 업데이트 해주는 함수라고 하자
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 updatedTest = updateTodo(todo, { title: "no!" }); //partial로 선언되어서 일부분만 들어와도 가능!
console.log(updated); // (1)
//(1)
{
title: 'no!',
description: 'study hard',
label: 'study',
priority: 'high'
}
말 그대로 기존의 타입에서 pick 해서 원하는 타입과 속성을 골라 쓸 수 있다.
많은 타입의 정보가 있고 그 중에 몇가지만 다루는 타입이 있을 경우 활용해 볼 수 있다.
/**
* From T, pick a set of properties whose keys are in the union K
*/
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
//아래와 같이 비디오 타입이 있다고 해보자. 타이틀과 컨텐츠, src, url등 다양한게 있다고 해보자.
type Video = {
id: string;
title: string;
url: string;
data: string;
description:string;
sub_url: string;
};
type VideoMetadata = Pick<Video, "id" | "title">; // T인 Video타입에서 골라서 union type으로 설정이 가능하다.
type VideoOnlyTitle = Pick<Vidoe, "id">;
function printVideoTitle(id:string):VideoMetadata{
return{
id,
title:"title",
}
}
/**
* Construct a type with the properties of T except for those in type K.
*/
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type VideoMetadata = Omit<Video, "url" | "data">; 위의 pick과 동일한 타입결과이다.
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
[P in K]: T;
};
//T를 value로 삼고 , K의 키를 Obejct의 key로 삼으면된다.
type PageInfo = {
title: string;
};
type Page = "home" | "about" | "contact";
const nav: Record<Page, PageInfo> = { // Page가 각 Key, PageInfo가 Value
home: { title: "Home" },
about: { title: "About" },
contact: { title: "Contact" },
};
드림코딩 엘리
https://dev.to/mattzgg_94/typescript-use-mapped-type-to-implement-a-proxy-4im2,