타입을 제네릭으로 바꾸었습니다. 검사하려는 타입이 제네릭이면서 유니언이면 분배법칙이 실행됩니다. Result<string | number>는 Result<string> | Result<number>가 됩니다. 따라서 Key extends string | boolean ? Key[] : never를 거치면 string [] | never가 되고, never는 사라져서 최종적으로 string[] 타입이 됩니다.
다만 boolean에 분배법칙이 적용될 때는 조심해야 합니다.
type Start = string | number | boolean;
type Result<Key> = Key extends string | boolean ? Key[] : never;
let n: Result<Start> = ['hi'];
// let n: string[] | false[] | true[]
n = [true];
string[] | boolean[]이 될 것이라는 예상과 달리 string[] | false[] | true[]가 됩니다. boolean을 true | false로 인식하기 때문입니다.
분배법칙이 일어나는 것을 막고 싶을 수도 있습니다. 다음과 같이 'hi' | 3이 string인지 검사하는 타입을 만들어보겠습니다. 3은 string이 아니므로 false가 나와야 합니다.
type IsString<T> = T extends string ? true : false;
type Result = IsString<'hi' | 3>;
// type Result = boolean