객체 유형에서 인덱스 시그니처를 제외하는 RemoveIndexSignature<T>를 구현하세요
정확하게는 string|number|symbol이 인덱스 시그니쳐
type RemoveIndexSignature<T> = {
[R in keyof T as string extends R?
never
:number extends R?
never
:symbol extends R?
never
:R]:T[R]
}
만약 R이 index-signiture라면, string extends R,number extends R,symbol extends R 중 하나가 true가 나오므로 키에 never를 주고, 그렇지 않다면 키에 R을 줘서 사용한다.
type RemoveIndexSignature<T, P=PropertyKey> = {
[K in keyof T as P extends K? never : K extends P ? K : never]: T[K]
}
이런 풀이도 있었다.
PropertyKey는 string | number | symbol이다.
참고로 분배법칙에 의해 string,number,symbol 타입이 mapped type의 key 타입에 있는 P에 각각 들어간다
P가 K를 확장하는 경우가 never이다.
P와 K를 확장하는 경우는 string과 string과 같이 시그니쳐 타입이므로 이를 제거해주는 작업이다.
P가 K를 확장하지 않는 경우를 살펴볼 수 있다.
1) 두 타입이 완전히 다른 경우 (P는 number, K는 string)
2) 두 타입이 겹치고, K가 P를 확장하는 경우 (P는 number, K는 1)
이때, 경우 2)에서만 K를 추출하려고 한다.
왜냐하면 경우 1)은 K를 검사하기 위해서 별로 필요없는 상황이기 때문이다.
이제 K extends P ? K : never가 경우 2)만 추출하는 경우인지를 살펴보자
경우 1)에서는 never가 나온다.
경우 2)에서는 K가 P를 확장하는 경우이다. 이때 P는 항상 string,number,symbol이고, K는 항상 string,number,symbol이 아니므로 우리가 원하는 K를 추출할 수 있다.
인덱스 시그니처가 사용되었다.
인덱스 시그니처의 특이한 점은 다음과 같다
obj[1]===obj[(1).toString()]) 그러므로 number형 인덱스 시그니처와 string형 인덱스 시그니처는 겹쳐야 한다.string에 대한 인덱스 시그니처가 있으면 일반 문자열을 키값으로 가진 밸류 값은 string에 대한 인덱스 시그니처와 겹쳐야 한다.https://github.com/type-challenges/type-challenges/issues/14662