과거 프로그래밍 자료들/Javascript&typescript
[TS] (utility types)Partial, Pick & Omit, Exclude, Extract 타입 분석
평부
2022. 9. 18. 16:19
출처 : https://github.com/ZeroCho/ts-all-in-one
https://github.com/microsoft/TypeScript/blob/main/lib/lib.es5.d.ts
* [lib.ex5.d.ts] Patial, Pick
type Partial<T> = {
[P in keyof T]?: T[P];
};
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
* [lib.ex5.d.ts] Omit, Exclude, Extract
▶ 타입에도 삼항연산자가 들어갈 수 있음
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
//예시
type Animal = "Cat" | "Dog" | "Human"
//type Mammal = "Cat" | "Dog"
type Mammal = Exclude<Animal, "Human"> //'Cat' | 'Dog' (never은 사라짐)
//필요한 부분 추출
type Human = Extract<Animal, 'Human'> //'Cat' | 'Dog' (never은 사라짐)
[Partial 예제 - 이런 상황을 해결하는 법 : Patial 사용하기]
//매번 같은 객체를 만드는 단점 존재
interface Profile {
name: string,
age: number,
married: boolean
}
//가능은 하나 중복됨
interface NewProfile {
name: string,
age: number,
}
const zerocho: Profile = {
name: "zerocho",
age: 29,
married: false
}
//married만 빼기 애매함
const newZeroCho: NewProfile = {
name: "zerocho",
age: 29
}
[Partial 사용하기 예제]
interface Profile {
name: string,
age: number,
married: boolean
}
const zerocho: Profile = {
name: "zerocho",
age: 29,
married: false
}
//Partial : Profile을 옵셔널로 만듦
//interface Profile {
// name?: string,
// age?: number,
// married?: boolean
// }
const newZeroCho: Partial<Profile> = {
name: "zerocho",
age: 29
}
[Partial을 P로 지정해서 직접 만들기 예제]
▶ Partial의 문제점 : Profile의 값들이 옵셔널로 되어 있어 const newZeroCho: P<Profile> = {}
이런 값도 문제 없다고 나옴
▶ Pick이나 Omit을 사용할 수 있음
//Partial을 P로 만들 수 있는가?
interface Profile {
name: string,
age: number,
married: boolean
}
//value 접근
//type Name = Profile['name'] (Profile.name이 아님)
type P<T> = {
//어떤 객체가 오든지 그 객체의 키를 아래에 씀
//아래의 자리에는 name, age, marreid가 옴 = 옵셔널로 만듦
[Key in keyof T]?: T[Key];
}
//type P<T>{}와 동일한 내용
//P<Profile>
//{
//Profile의 키를 다 꺼냄
//name?: string,
//age?: number,
//married?: boolean
//}
const zerocho: Profile = {
name: "zerocho",
age: 29,
married: false
}
const newZeroCho: P<Profile> = {
name: "zerocho",
age: 29
}
* Pick이나 Omit 사용하는 경우
interface Profile {
name: string,
age: number,
married: boolean
}
const zerocho: Profile = {
name: "zerocho",
age: 29,
married: false
}
//Pick은 Profile에서 name과 age만 가져옴
const newZeroCho: Pick<Profile, 'name' | 'age'> = {
name: "zerocho",
age: 29
}
//Omit : Profile에서 married만 제외
const newZeroCho2: Omit<Profile, "married"> = {
name: "zerocho",
age: 29
}
* Pick을 직접 만드는 경우
interface Profile {
name: string,
age: number,
married: boolean
}
//Pick을 직접 만듦
//S가 아무 값이나 되는 게 아닌 T랑 연관되야 함
type P<T, S extends keyof T> = {
[Key in S]: T[Key];
}
const zerocho: Profile = {
name: "zerocho",
age: 29,
married: false
}
//Pick을 P로 만듦
//제한조건인 name, age를 먼저 써야 함
const newZeroCho: P<Profile, 'name' | 'age'> = {
name: "zerocho",
age: 29
}
* Omit
interface Profile {
name: string,
age: number,
married: boolean
}
const zerocho: Profile = {
name: "zerocho",
age: 29,
married: false
}
// type A = Exclude<keyof Profile, 'married'>
//Omit 만들기
//keyof 붙는 이유 Profile 자체가 아닌 "name" | "age" | "married"를 원하기 때문
//S의 제한조건을 붙임
type O<T, S extends keyof any> = Pick<T, Exclude<keyof T, S>>
const newZeroCho: O<Profile, "married"> = {
name: "zerocho",
age: 29
}