interface Person {
name: string;
age: number;
nickname: string;
phone: string;
}
위와 같은 Person 인터페이스가 있을 때, name과 age만 필요한 타입이 필요하다면?
// 이렇게 새로 정의할 수 있겠지만
interface SubPerson {
name: string;
age: number;
}
// Pick을 이용하면, 위 SubPerson과 동일하다.
type SubPerson = Pick<Person, 'name' | 'age'>
vscode에서 SubPerson에 마우스오버하면, 아래와 같이 정의된 타입을 확인할 수 있다.
Pick과 반대
// 제외할 Key를 두번째 인자로 입력. 이렇게 하면 위 SubPerson Type과 동일하다.
type SubPerson = Omit<Person, 'nickname' | 'phone'>
<TYPE>
- TYPE의 모든 속성을 선택적으로 변경한 새로운 타입 반환// SubPerson Type의 모든 속성을 선택적으로 변경
interface UpdateSubPerson {
name?: string;
age?: number;
}
// Partial을 이용하여 정의 - 위 UpdateSubPerson 타입과 동일하다.
type UpdateSubPerson = Partial<SubPerson>;
Partial Type은 ts에 아래와 같이 정의되어 있다.
type Partial<T> = {
[P in keyof T]?: T[P];
};
T의 Key를 돌면서, 각 Key는 T[P]로 정의하겠다. 는 의미인데..
위 코드가 되기까지 과정을 살펴보자면
// 만들고자 하는 유형의 형태
type UpdateSubPerson = {
name?: string;
age?: number;
}
// 만들고자 하는 유형의 형태는 이렇게 SubPerson의 type을 가져와서 정의할 수 있고
type UpdateSubPerson = {
name?: SubPerson['name'];
age?: SubPerson['age'];
}
// mapped type으로 표현하면..
type UpdateSubPerson = {
[p in 'name' | 'age']?: SubPerson[p];
}
// name, age는 SubPerson의 key 들이므로
type UpdateSubPerson = {
[p in keyof SubPerson]?: SubPerson[p];
}
// 모든 객체에 적용하기 위해, 제네릭으로 표현하면.. 마침내 같은 형태가 된다.
type Subset<T> = {
[p in keyof T]?: T[p];
}
이전 타입을 기반으로 새로운 타입을 생성
위에 Partial 을 구현하는 과정에서 잠시 나왔었지만.. 기존 js 문법 for..in 구문과 유사하다.
type Keys = 'option1' | 'option2';
type Flags = { [K in Keys]: boolean };
// 위와 같이 정의했을 경우 Flags는 아래와 같다.
type Flags = {
option1: boolean;
option2: boolean;
}
// Flags 타입의 변수 선언
const obj: Flags = {
option1: true,
option1: false
}