서로 다른 타입 변수를 여러 개 동시에 사용할 수도 있습니다.
type MyPAndR<T> = T extends (...args: infer P) => infer R ? [P, R] : never;
type PR = MyPAndR<(a: string, b: number) => string>;
// type PR = [[a: number, b: string], string]
매개변수는 P 타입 변수로, 반환값은 R 타입 변수로 추론한 모습입니다.
반대로 같은 타입 변수를 여러 곳에 사용할 수도 있습니다.
type Union<T> = T extends { a: infer U, b: infer U } ? U : never;
type Result1 = Union<{ a: 1 | 2, b: 2 | 3 }>;
// type Result1 = 1 | 2 | 3
type Intersection<T> = T extends {
a: (pa: infer U) => void,
b: (pb: infer U) => void
} ? U : never;
type Result2 = Intersection<{ a(pa: 1 | 2): void, b(pb: 2 | 3): void }>;
// type Result2 = 2
Union<T> 타입에서는 a와 b 속성의 타입을 모두 U 타입 변수로 선언했습니다. Union 타입을 사용할 때는 a에 1 | 2를, b에 2 | 3 타입을 넣었습니다. 그랬더니 Result1은 1 | 2 | 3이 되었습니다. 이는 a와 b의 유니언입니다. 이처럼 같은 이름의 타입 변수는 서로 유니언이 됩니다.