/*
12 - Chainable Options
-------
by Anthony Fu (@antfu) #medium #application
### Question
Chainable options are commonly used in Javascript. But when we switch to TypeScript, can you properly type it?
In this challenge, you need to type an object or a class - whatever you like - to provide two function `option(key, value)` and `get()`. In `option`, you can extend the the current config type by the given key and value. We should about to access the final result via `get`.
For example
```ts
declare const config: Chainable
const result = config
.option('foo', 123)
.option('name', 'type-challenges')
.option('bar', { value: 'Hello World' })
.get()
// expect the type of result to be:
interface Result {
foo: number
name: string
bar: {
value: string
}
}
You don't need to write any js/ts logic to handle the problem - just in type level.
You can assume that key
only accept string
and the value
and be anything - just leave it as-is. Same key
won't be passed twice.
View on GitHub: https://tsch.js.org/12 */
/* _____________ Your Code Here _____________ */
type Chainable = { option(key: string, value: any): any get(): any }
/* _____________ Test Cases _____________ */ import { Alike, Expect } from '@type-challenges/utils'
declare const a: Chainable
const result = a .option('foo', 123) .option('bar', { value: 'Hello World' }) .option('name', 'type-challenges') .get()
type cases = [ Expect<Alike<typeof result, Expected>> ]
type Expected = { foo: number bar: { value: string } name: string }
/* _____________ Further Steps _____________ / /
Share your solutions: https://tsch.js.org/12/answer View solutions: https://tsch.js.org/12/solutions More Challenges: https://tsch.js.org */
Chainable 이라는 타입을 만들어야 하는데 이 타입은 option 이라는 메소드로 키, 밸류를 받아서 get 메소드를 실행하면 만들어진 객체를 리턴하는 타입이다.
답은
```tsx
type Chainable<T = {}> = {
option<K extends string, V>(key: K, value: V): Chainable<T & { [P in K]: V }>
get(): {
[k in keyof T]: T[k]
}
}
어려웠다.... 그래서 답안지 봤다...
Chainable<T & { K: V }>
키를 매핑타입으로 꺼내 주어야 했다.
Chainable<T & { [k in K]: V }>
사실 잘 이해가 안 가긴 한다.
테스트 해보자.
테스트1
type A1<K extends string, V, T = {}> = T & { K: V }