본문 바로가기
스터디

[Typescript] 유틸리티 타입

by rious275 2023. 6. 19.

TypeScript는 공통 타입 변환을 용이하게 하기 위해 몇 가지 유틸리티 타입을 제공하며, 이런 유틸리티들은 전역으로 사용이 가능하다.

Partial

T의 모든 프로퍼티를 선택적으로 만드는 타입을 구성하며, 주어진 타입의 모든 하위 타입 집합을 반환한다.

interface Types {
  title: string;
  description: string;
}

// 아래 둘 다 허용
const todo1: Types = { title: 'todo_01', description: 'todo_01' };

const todo2: Partial<Types> = { title: 'todo_02' };

Readonly

T의 모든 프로퍼티를 읽기 전용(readonly)으로 설정한 타입을 구성하며 생성된 타입의 프로퍼티는 재할당할 수 없다.

interface Types {
  title: string;
}

const todo: Readonly<Types> = { title: 'todo' };

todo.title = 'hello'; // X 재할당 불가능

Record<K, T>

T의 프로퍼티 집합(K)을 지정한다.

interface PageInfo {
  title: string;
}

type Page = 'home' | 'about' | 'contact';

// 각 프로퍼티에 PageInfo가 지정된다.
const test: Record<Page, PageInfo> = {
  home: { title: 'home' },
  about: { title: 'home' },
  contact: { title: 'home' },
};

Pick<T, K>

T에서 프로퍼티 집합 K를 선택해 타입을 구성한다.

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

// Todo 타입에서, title과 completed만 사용
type TodoPreview = Pick<Todo, 'title' | 'completed'>;

const todo: TodoPreview = {
  title: 'Clean room',
  completed: false,
};

Omit<T, K>

T에서 프로퍼티 집합 K를 제거 후 구성한다.

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

// Todo 타입 구성에서 description만 제외
type TodoPreview = Omit<Todo, 'description'>;

const todo: TodoPreview = {
  title: 'Clean room',
  completed: false,
};

Exclude<T, U>

T에서 특정 타입 속성 U를 제외한 타입을 구성한다.

type Type = 'a' | 'b' | 'c';

// Type에서 a만 제외 후 구성
type CurrentType = Exclude<Type, 'a'>;

const a: CurrentType = 'c';

Extract<T, U>

T에서 특정 타입 속성 U에 할당할 수 있는 모든 속성을 추출하여 타입을 구성한다.

type Type = 'a' | 'b' | 'c';

// Type에서 a나 f 속성만 추출해 타입 구성
type Example = Extract<Type, 'a' | 'f'>;

NonNullable

T에서 null, undefined를 제외한 타입을 구성한다.

// string과 number만 살아남는다.
type Example = NonNullable<string | number | null>;

Parameters

함수 타입 T의 매개변수 타입들의 튜플 타입을 구성한다.

declare function f1(a: number, b: string): void;

// [number, string] 튜플 타입 구성
type Type = Parameters<typeof f1>;

const example: Type = [3, 'text']; // O
const example2: Type = ['text', 'text2']; // X

ConstructorParameters

생성자 함수 타입의 모든 매개변수 타입을 추출하며, 모든 매개변수 타입을 가지는 튜플 타입을 생성한다.

단, T가 함수가 아닌 경우 never 타입 생성.

// 생성자 함수의 매개변수 튜플 타입 구성 [number, string]
type Type = ConstructorParameters<new (a: number, b: string) => void>;
const arr: Type = [5, 'text']; // O

// 클래스 예시
class TestClass {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

type Type2 = ConstructorParameters<typeof TestClass>;
const arr2: Type2 = ['text', 2]; // O

ReturnType

함수 T의 반환 타입으로 구성된 타입 생성한다.

// 표현식의 리턴 타입인 string으로 구성
type Type = ReturnType<() => string>;
const example: Type = 'hello';

InstanceType

생성자 함수 타입 T의 인스턴스 타입으로 구성된 타입을 만든다.

class Class {
  a: string;
  b: number;
}

type Type = InstanceType<typeof Class>;

const obj: Type = {
  a: 'hello',
  b: 51,
};

Required

T의 모든 프로퍼티가 필수인 타입을 구성한다.

interface Types {
  a?: number;
  b?: string;
}

const obj: Required<Types> = { a: 5 }; // X

ThisParameterType

함수 타입 매개변수에 this가 없을 경우 unknown을 추출한다.

--strictFunctionTypes 기능이 활성화되었을 때만 동작

function toHex(this: number) {
  return this.toString(16);
}

// 함수 toHex에 this가 있으므로 number 타입 구성
function numberToString(n: ThisParameterType<typeof toHex>) {
  return toHex.apply(n);
}

numberToString('text'); // X

OmitThisParameter

함수 타입에서 this 매개변수를 제거한다.

--strictFunctionTypes 기능이 활성화되었을 때만 동작

function toHex(this: number) {
  return this.toString(16);
}

// this를 제거했으므로 타입을 받지 않음
const fiveToHex: OmitThisParameter<typeof toHex> = toHex.bind(2);

console.log(fiveToHex());

ThisType

문맥적 this 타입에 표시하는 역할을 한다.

--noImplicitThis 기능이 활성화되었을 때만 동작(true로 설정하면, this가 가리키는 것이 명확하지 않으면 에러 발생)

type ObjectDescriptor<D, M> = {
  data?: D;
  methods?: M & ThisType<D & M>; // 메서드 안의 'this 타입은 D & M
};

function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
  return { ...desc.data, ...desc.methods };
}

let obj = makeObject({
  data: { x: 0, y: 0 },
  methods: {
    moveBy(dx: number, dy: number) {
      this.x += dx;
      this.y += dy;
    },
  },
});

// this는 data 타입 추론에 의해
// { x: number, y: number } & { moveBy(dx: number, dy: number): D & M }

obj.x = 'hello'; // X
obj.y = 20; // O
obj.moveBy(5, 5); // O

'스터디' 카테고리의 다른 글

[Typescript] 모듈 해석  (0) 2023.07.09
[Typescript] 모듈 (module)  (0) 2023.07.07
[Typescript] 제네릭 (Generics)  (0) 2023.06.12
[Typescript] 열거형 (Enums)  (0) 2023.06.11
[Typescript] 유니언 타입과 교차 타입  (0) 2023.06.11