때때로 유니온 타입의 특정 속성을 기준으로 조회할 수도 있습니다.
이 챌린지에서는 유니온 타입 Cat | Dog에서 공통으로 사용하는 type 필드를 기준으로 해당하는 타입을 얻고자 합니다. 다시 말해서, 다음 예시에서는 LookUp<Cat | Dog, 'dog'>으로 Dog 타입을, LookUp<Cat | Dog, 'cat'>으로 Cat 타입을 얻을 수 있습니다.
type LookUp<U extends {'type':any }, T,Union=U> =
U extends Union?
Equal<U['type'],T> extends true? U:never
:never
U를 분배법칙으로 사용하기 위해 Union이라는 별도의 타입을 두었다.
또 Equal이라는 타입챌린지 자체 제공 타입을 통해 타입이 같은지를 확인했다.
type LookUp<U, T extends string> = {
[K in T]: U extends { type: T } ? U : never
}[T]
T의 모든 값을 mapped타입의 키 타입으로 두고, U를 분배 법칙으로 밸류 타입으로 둔뒤, 해당 mapped 타입의 T가 키인 값들을 반환하는 식으로 하였다.
이 풀이는 깔끔하긴 하지만, T가 string으로 제한된다는 단점이 있는 듯 하다.
type LookUp<U, T> = U extends {type: T} ? U : never;
이 풀이도 좋은 방법이다. 나의 풀이처럼 쓸데없는 제네릭이 필요가 없다.
내 풀이와의 차이점을 찾아보자면,
내 풀이의 경우 완전히 같은 타입이여야지 타입이 반환이 되고,
이 풀이에서는 하위 호환하는 타입이여도 타입이 반환이 된다.
이와 관련하여, U에 문제에서 제공한Dog|Cat 을 넣고 T에 string을 넣는 경우를 생각해볼 수 있다.
내 타입은 두 타입 모두 반환하지 못하지만,
이 타입은 두 타입 모두 반환하게 된다.
직관적으로 봤을 때,
이 풀이가 더 나은 풀이라는 생각이 든다.
언제 분배법칙으로 사용할 수 있을까?
이와 관련된 자료는 타입스크립트 공식 문서에서 확인할 수 있다.
제네릭 타입 뒤에 조건부 타입(... extends ... ? ... : ...)이 올 경우 자동으로 분배법칙이 적용된다.
내 풀이의 경우 Union타입을 통해 분배 법칙을 일으킨다
https://github.com/type-challenges/type-challenges/issues/75
https://github.com/type-challenges/type-challenges/issues/149
https://www.typescriptlang.org/ko/docs/handbook/2/conditional-types.html#%EB%B6%84%EC%82%B0%EC%A0%81%EC%9D%B8-%EC%A1%B0%EA%B1%B4%EB%B6%80-%ED%83%80%EC%9E%85