bh2980.dev

12 - Chainable Options

  • #Type Challenges
  • #TypeScript

질문

체인 가능 옵션은 일반적으로 Javascript에서 사용됩니다. 하지만 TypeScript로 전환하면 제대로 구현할 수 있나요?

이 챌린지에서는 option(key, value)get() 두가지 함수를 제공하는 객체(또는 클래스) 타입을 구현해야 합니다. 현재 타입을 option으로 지정된 키와 값으로 확장할 수 있고 get으로 최종 결과를 가져올 수 있어야 합니다.

declare const config: Chainable

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

// 결과는 다음과 같습니다:
interface Result {
  foo: number
  name: string
  bar: {
    value: string
  }
}

/* _____________ 테스트 케이스 _____________ */
import type { Alike, Expect } from '@type-challenges/utils' declare const a: Chainable 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 cases = [ Expect<Alike<typeof result1, Expected1>>, Expect<Alike<typeof result2, Expected2>>, Expect<Alike<typeof result3, Expected3>>, ] type Expected1 = { foo: number bar: { value: string } name: string } type Expected2 = { name: string } type Expected3 = { name: number }

문제를 해결하기 위해 js/ts 로직을 작성할 필요는 없습니다. 단지 타입 수준입니다.

keystring만 허용하고 value는 무엇이든 될 수 있다고 가정합니다. 같은 key는 다시 전달할 수 없습니다.

선행 지식

  1. 메서드 타입 정의 방법

    type Example = {
     test(): any\n}
    
     // or
     
     type Example = {
       test: () => any
     }

    메서드는 위처럼 2가지 형태로 타입을 정의할 수 있다.

  2. 타입 스크립트에서 에러 내기

    타입 시스템은 런타임이 아니므로 throw new Error() 같은 방식으로 에러를 낼 수 없다. 대신 타입이 성립하지 않도록 만들어 컴파일 타임 에러를 유도한다.

    가장 자주 쓰는 방식은 특정 인자의 타입을 never로 만들어 호출을 막는 것이다.

풀이