kakasoo

Chainable, 연쇄적인 호출이 가능한 타입 본문

프로그래밍/TypeScript

Chainable, 연쇄적인 호출이 가능한 타입

카카수(kakasoo) 2023. 2. 21. 00:04
반응형
type Chainable<T = {}> = {
  option<K extends string, P>(key: K, value: P): Chainable<Omit<T, K> & Record<K, P>>;
  get(): T;
}

const result1 = a
  .option('foo', 123)
  .option('bar', { value: 'Hello World' })
  .option('name', 'type-challenges')
  .get()

const result2 = a
  .option('name', 'another name'
  // @ts-expect-error
  .option('name', 'last name')
  .get()

const result3 = a
  .option('name', 'another name')
  // @ts-expect-error
  .option('name', 123)
  .get()
type Expected1 = {
  foo: number
  bar: {
    value: string
  }
  name: string
}

type Expected2 = {
  name: string
}

type Expected3 = {
  name: number
}

option이라는 메서드를 계속적으로 호출해가며 원하는 객체 모양을 만들 수 있는 type Chainable을 구현했다.

Chainable은 시작 타입 파라미터로 빈 객체인 T를 가지고 있으며,

option 메서드는 계속 해서 호출되어야 하기에 무조건 Chainable 타입을 반환해야만 했다.

옵션의 두 파라미터 key, value는 string과 아직 확정되지 않은 any 타입을 가진 K, P로 정의되었다.

이 함수의 결과 값은 Chainable이기에, 1차적으로 Chainable<T, & Record<K, P>>가 되어야 했다.

하지만 문제에 주어진 조건과 같이 동일한 key로 선언할 경우 후에 선언한 게 더 우선시되어야만 한다.

따라서 Chainable<Omit<T, K> & Record<K, P>>가 가장 적합하다.

이전에 할당을 했든 안했든 일단 K를 T로부터 지우고, 다시 K에 새로운 타입을 정의하는 것이다.

반응형