TypeScript

TypeScript - Utility Type 정리

개발하길잘햇다 2021. 12. 19. 23:13
반응형

현재 내가 속한 회사에서는 개발자 모임이라는 시간을 한 달에 한 번씩 갖는다. 서로 공유하면 좋을 내용들과 개발적인 대화를 하는 매우 생산적이고 좋은 문화라고 생각하며, 이번에 그 시간을 적극적으로 활용해보기 위해 타입 스크립트에서 사용할 수 있는 유틸리티 타입에 대한 간단 소개 발표를 하게 되었다.

 

아래 내용은 이번 발표에 사용한 예시자료들이다.

 

유틸리티 타입(Utility Type)

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

 

 

Partial<T>

  • 특정 타입의 부분 집합을 만족하는 타입을 정의할 수 있다.
  • 옵셔널 파라미터(?)를 사용하지 않아도 에러가 발생하지 않는다.
interface Address {
  email: string;
  address: string;
}

type Info = Partial<Address>;

const A: Info = {}; // 가능
const B: Info = { email: 'test@test.com' }; // 가능
const C: Info = { email: 'test@test.com', address: 'Sinsa' }; // 가능

 

 

Readonly<T>

  • T 의 모든 프로퍼티를 읽기 전용(readonly)으로 설정한 타입을 구성한다. 즉 생성된 타입의 프로퍼티는 재할당 할 수 없고 오직 참조만 가능하다.
interface Todo {
    title: string;
}

const todo: Readonly<Todo> = {
    title: 'Delete inactive users',
};

todo.title = 'Hello'; // 오류: 읽기 전용 프로퍼티에 재할당할 수 없음

 

 

Record<K, T>

  • K 타입을 key값으로, T 타입을 value 값으로 갖는 형태의 타입을 생성한다. ex : [ K ] : T
  • 주로 K에 유니온 문자열 값을 주어 map 형식의 타입을 만들 수 있고 여러 값들을 원하는 키값에 따라 분류할 때 유용하다.
interface Car {
    name: string,
    price: number
}

const productList: Record<"SONATA" | "AVANTE", Car> = {
    SONATA: {name: "SONATA", price: 10000},
    AVANTE: {name: "SONATA", price: 10000}
}

const nextProductList: Record<string, Car> = {
    SONATA: {name: "SONATA", price: 10000},
    AVANTE1: {name: "SONATA", price: 10000},
    AVANTE2: {name: "SONATA", price: 10000},
    AVANTE3: {name: "SONATA", price: 10000},
}

 

 

Pick<T, K>

  • 특정 타입에서 몇 개의 속성을  선택(pick)하여 타입을 정의할 수 있습니다.
  • Pick<대상타입, 선택할 속성>
interface BurgerSet {
  burger: string;
  potatoChip: string;
	beverage: string;
}

const burgerSingle: Pick<BurgerSet, 'burger'> = {
  burger: '치즈버거 단품',
};

// 두개 이상 사용시
const burgerKing: Pick<BergerSet, 'burger'|'beberage'> = {
  burger: '와퍼 단품',
  beverage: '코카콜라'
};

 

 

Omit<T, K>

  • 특정 타입에서 지정된 속성만 제거한 타입을 정의해 줍니다.
  • Omit<대상타입, 뺄속성>
interface AddressBook {
  name: string;
  phone: number;
  address: string;
  company: string;
}

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

// 두개이상 지정할때
const chingtao: Omit<AddressBook, 'address'|'company'> = {
  name: '중국집',
  phone: 02-111-8888
}

 

 

Exclude<T, U>

  • T 타입들 중 U타입들과 겹치는 타입을 제외합니다.
type T0 = Exclude<"a" | "b" | "c", "a">;        // "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">;  // "c"
type T2 = Exclude<string | number | (() => void), Function>;  // string | number


type ABC = "A" | "B" | 13
type A0 = Exclude<ABC , string> ; // 13

 

 

Extract<T, U>

  • T타입에서 U 타입과 겹치는 타입만을 가져옵니다.
type T0 = Extract<"a" | "b" | "c", "a" | "f">;  // "a"
type T1 = Extract<string | number | (() => void), Function>;  // () => void


type ABC = "A" | "B" | 13
type A0 = Extract<ABC , string> ; // "A" | "B"

 

 

NonNullable<T>

  • T 타입에서 Null or undefined 를 제외하고 리턴합니다.
type T0 = NonNullable<string | number | undefined>;  // string | number
type T1 = NonNullable<string[] | null | undefined>;  // string[]

 

 

Parameters<T>

  • 함수의 파라미터를 튜플[] 타입으로 리턴합니다.
function f1(arg: { a: number, b: string }): void

type T0 = Parameters<() => string>;  // []
type T1 = Parameters<(s: string) => void>;  // [string]
type T2 = Parameters<(<T>(arg: T) => T)>;  // [unknown]
type T4 = Parameters<typeof f1>;  // [{ a: number, b: string }]
type T5 = Parameters<any>;  // unknown[]

type T6 = Parameters<never>;  // any
// never는 any를 제외한 모든 타입의 원시타입이기때문에
// 함수타입 T에 never로 주어도 에러가 발생하지 않고
// 인자값으로도 어떠한 값이든 올 수 있기때문에 any가 리턴됩니다.


// 함수형태가 아닌 타입이 T 자리에 오면 에러가 발생합니다.
type T7 = Parameters<string>;  // Error
type T8 = Parameters<Function>;  // Error


//활용
const myName: T1 = ["joo"]
const myProfile : T4 = [{a: '13', b:'나이'}]

 

 

ConstructorParameters<T>

  • 생성자 함수 타입의 모든 매개변수 타입을 추출할 수 있게 해 줍니다. 모든 매개변수 타입을 가지는 튜플 타입(T가 함수가 아닌 경우 never)을 생성합니다.
// 예제 1

type T0 = ConstructorParameters<ErrorConstructor>;  // [(string | undefined)?]
type T1 = ConstructorParameters<FunctionConstructor>;  // string[]
type T2 = ConstructorParameters<RegExpConstructor>;  // [string, (string | undefined)?]

예제 1 보충 자료

ErrorContructor

FunctionConstructor

RegExpConstructor

// 예제 2

class Person {
    private _firstname: string
    private _lastname: string

    constructor(firstname: string, lastname: string) {
        this._firstname = firstname
        this._lastname = lastname
    }
}

type constructuinArgsType = ConstructorParameters<typeof Person>;
// [firstname: string, lastname: string]

let personConstructionArgs: constructuinArgsType = ['first', 'last']

 

 

ReturnType<T>

  • 함수 T의 반환 타입으로 구성된 타입을 만듭니다.
declare function f1(): { a: number, b: string }

type T0 = ReturnType<() => string>;  // string
type T1 = ReturnType<(s: string) => void>;  // void
type T2 = ReturnType<(<T>() => T)>;  // {}
type T3 = ReturnType<(<T extends U, U extends number[]>() => T)>;  // number[]
type T4 = ReturnType<typeof f1>;  // { a: number, b: string }
type T5 = ReturnType<any>;  // any
type T6 = ReturnType<never>;  // any
// never는 any를 제외한 모든 타입의 원시타입이기때문에
// 함수타입 T에 never로 주어도 에러가 발생하지 않고
// 인자값으로도 어떠한 값이든 올 수 있기때문에 any가 리턴됩니다.


type T7 = ReturnType<string>;  // 오류
// 함수타입이 아님

type T8 = ReturnType<Function>;  // 오류
// return값이 있는 함수형태가 아님

 

 

InstanceType<T>

  • 생성자로 초기화된 인스턴스 타입을 리턴합니다.
let funTest = () => ({ a: 23, b: 33 });

type T0 = ReturnType<() => string>;  // string
type T1 = ReturnType<(s: string) => void>;  // void
type T2 = ReturnType<(<T>() => T)>;  // {}
type T3 = ReturnType<(<T extends U, U extends number[]>() => T)>;  // number[]
type T4 = ReturnType<typeof funTest>;  // { a: number, b: string }
type T5 = ReturnType<any>;  // any
type T6 = ReturnType<never>;  // any

 

 

Required<T>

  • T의 모든 프로퍼티가 필수로 설정된 타입을 구성합니다.
interface Props {
    a?: number;
    b?: string;
};

// 적용 전
const obj: Props = { a: 5 }; // 성공

// 적용 후
const obj2: Required<Props> = { a: 5 }; // 오류: 프로퍼티 'b'가 없습니다

 

 

 

참고 자료 출처

https://typescript-kr.github.io/pages/utility-types.html

 

TypeScript 한글 문서

TypeScript 한글 번역 문서입니다

typescript-kr.github.io

https://medium.com/harrythegreat/typescript-%EC%9C%A0%ED%8B%B8%EB%A6%AC%ED%8B%B0-%ED%81%B4%EB%9E%98%EC%8A%A4-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-7ae8a786fb20

 

Typescript 유틸리티 클래스 파헤치기

Utility Types Docs를 중점으로

medium.com

 

반응형