/*
62 - Type Lookup
-------
by Anthony Fu (@antfu) #medium #union #map
### Question
Sometimes, you may want to lookup for a type in a union to by their attributes.
In this challenge, we would like to get the corresponding type by searching for the common `type` field in the union `Cat | Dog`. In other words, we will expect to get `Dog` for `LookUp<Dog | Cat, 'dog'>` and `Cat` for `LookUp<Dog | Cat, 'cat'>` in the following example.
```ts
interface Cat {
type: 'cat'
breeds: 'Abyssinian' | 'Shorthair' | 'Curl' | 'Bengal'
}
interface Dog {
type: 'dog'
breeds: 'Hound' | 'Brittany' | 'Bulldog' | 'Boxer'
color: 'brown' | 'white' | 'black'
}
const MyDog = LookUp<Cat | Dog, 'dog'> // expected to be `Dog`
View on GitHub: https://tsch.js.org/62 */
/* _____________ Your Code Here _____________ */
type LookUp<U, T> = any
/* _____________ Test Cases _____________ */ import { Equal, Expect } from '@type-challenges/utils'
interface Cat { type: 'cat' breeds: 'Abyssinian' | 'Shorthair' | 'Curl' | 'Bengal' }
interface Dog { type: 'dog' breeds: 'Hound' | 'Brittany' | 'Bulldog' | 'Boxer' color: 'brown' | 'white' | 'black' }
type Animal = Cat | Dog
type cases = [ Expect<Equal<LookUp<Animal, 'dog'>, Dog>>, Expect<Equal<LookUp<Animal, 'cat'>, Cat>>, ]
/* _____________ Further Steps _____________ / /
Share your solutions: https://tsch.js.org/62/answer View solutions: https://tsch.js.org/62/solutions More Challenges: https://tsch.js.org */
타입을 추론할 수 있도록 돕는 것이 관건 인 것 같다.
놀라운 솔루션을 참고했다.
```tsx
type LookUp<U, T> = U extends {type: T} ? U : never;
U
의 조건문으로 { type: T }
인 경우 U
를 리턴하게 했다. 이 과정을 통해서 똑똑한 컴파일러가 타입을 추론하게 된다. 만약 서로 일치하지 않는 다면 never
를 리턴한다. 아주 합리적이다.
T
가 'dog'
이면 조건문 에서 type: 'dog'
이 되니깐 U
를 리턴할 때 type: 'dog'
프로퍼티를 가진 객체를 리턴하는 것이다!
좀더 스트릭하게 쓸 수 있도록 바꿔 보았다.
type LookUp<U extends { type: string }, T extends U['type']> = U extends { type: T } ? U : never