17. 유틸리티 타입

CHOYEAH·2023년 11월 5일
0

TypeScript

목록 보기
17/23
post-custom-banner

Documentation - Utility Types

  • 유틸리티 타입은 이미 정의해 놓은 타입을 “변환”할 때 사용하기 좋은 타입 문법.
  • 기존의 인터페이스, 제네릭 등의 기본 문법으로 충분히 타입을 변환할 수 있지만 유틸리티 타입을 쓰면 훨씬 더 간결한 문법으로 타입을 정의할 수 있다.
  • API성의 타입

Pick


interface Product {
    id: number;
    name: string;
    price: number;
    brand: string;
    stock: number;
}

interface ProductDetail {
    id: number;
    name: string;
    price: number; 
}

function fetchProducts(): Promise<Product[]> {
  // ..
}

function displayProductDetail( item: ProductDetail) {

}

Product의 부분 집합인 ProductDetail을 새롭게 정의하여 함수의 인자로 사용하고있다.

interface Product {
    id: number;
    name: string;
    price: number;
    brand: string;
    stock: number;
}

function fetchProducts(): Promise<Product[]> {
  // ..
}

// 변수가 아닌 type으로 받음을 유의 
type detailItem = Pick<Product, "id" | "name" | "price">
function displayProductDetail( item: detailItem){

}

Pick을 사용하면 특정 구조에서 유니온 표현식으로 원하는 속성만 가져와 타입을 정의할 수 있다.

Pick은 변수가 아닌 type으로 받을 수 있음에 유의.

Omit


오밋(Omit) 타입은 특정 타입에서 지정된 속성만 제거한 타입을 정의해준다.

interface AddressBook {
  name: string;
  phone: number;
  address: string;
  company: string;
}

const phoneBook: Omit<AddressBook, 'address'> = {
  name: '재택근무',
  phone: 12342223333,
  company: '내 방'
}

const chingtao: Omit<AddressBook, 'address'|'company'> = {
  name: '중국집',
  phone: 44455557777
}

Partial


파셜(Partial) 타입은 특정 타입의 부분 집합을 만족하는 타입을 정의할 수 있다.

interface Address {
  email: string;
  address: string;
}

type MayHaveEmail = Partial<Address>;
const me: MayHaveEmail = {}; // 가능
const you: MayHaveEmail = { email: 'test@abc.com' }; // 가능
const all: MayHaveEmail = { email: 'capt@hero.com', address: 'Pangyo' }; // 가능
interface Product {
    id: number;
    name: string;
    price: number;
    brand: string;
    stock: number;
}

interface UpdateProduct {
    id?: number;
    name?: string;
    price?: number;
    brand?: string;
    stock?: number; 
}

function updateProductItem(productItem: UpdateProduct) {
  // Product의 어떤 속성이든 업데이트할 수 있도록 인자를 받고자 한다. 
}

상품을 업데이트하는 함수에 사용할 인터페이스를 정의하고 인자로 사용하였다.

매번 모든 속성을 받아서 업데이트하지 않기 위하여 UpdateProduct 인터페이스를 정의하였다.

위와 같은 상황에서 Partial을 사용하면 다음과 같이 새롭게 인터페이스를 정의하지 않아도 된다.

interface Product {
    id: number;
    name: string;
    price: number;
    brand: string;
    stock: number;
}

type UpdateProduct = Partial<Product>;
function updateProductItem(productItem: UpdateProduct) {
  // Product의 어떤 속성이든 업데이트할 수 있도록 인자를 받고자 한다. 
}
  • Parial 타입 해석 다음은 라이브러리에서 열어본 파셜의 구현체이다.

   interface UserProfile {
       username: string;
       email: string;
       profilePhotoUrl: string;
   }
   
   // UserProfile을 업데이트하기 위한 새로운 타입을 정의하려고한다.
   
   // #1 UserProfile의 모든 속성중 어떤 속성이든 취할 수 있는 인터페이스를 만들었다.
   interface UserProfileUpdate {
       username?: string;
       email?: string;
       profilePhotoUrl?: string;
   }
   
   // #2 1에서 작성한 타입 부분을 UserProfile 인터페이스의 키를 사용하여 타입을 정의하였다.
   type UserProfileUpdate = {
       username?: UserProfile['username'];
       email?: UserProfile['email'];
       profilePhotoUrl?: UserProfile['profilePhotoUrl']; 
   } 
   
   // #3 맵드 타입을 사용하여 한 줄로 표현하였다.
   type UserProfileUpdate = {
       [p in 'username' | 'email' | 'profilePhotoUrl']?: UserProfile[p];
   } 
   
   // #4 keyof를 사용하여 보다 축약시켰다.
   type UserProfileUpdate = {
       [p in keyof UserProfile]?: UserProfile[p];
   }
   
   // #5 제네릭을 사용하여 어떤 타입도 활용 가능하도록 수정하였다. 
   type Partial<T> = {
       [p in keyof T]?: T[p];
   }
profile
Move fast & break things
post-custom-banner

0개의 댓글