Bạn muốn liên minh đến giao lộ? Các kiểu điều kiện phân tán và suy luận từ các kiểu điều kiện có thể làm được điều đó. (Tuy nhiên, đừng nghĩ rằng có thể thực hiện giao nhau, xin lỗi) Đây là phép thuật xấu xa:
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
Điều đó phân phối liên minh Uvà đóng gói lại nó thành một liên minh mới, nơi tất cả các thành phần đều ở vị trí trái ngược nhau. Điều đó cho phép loại được suy ra là một giao điểm I, như đã đề cập trong sổ tay:
Tương tự như vậy, nhiều ứng cử viên cho cùng một biến loại ở các vị trí khác nhau khiến loại giao nhau được suy ra.
Hãy xem nếu nó hoạt động.
Trước tiên, hãy để tôi đặt dấu ngoặc đơn của bạn FunctionUnionvà FunctionIntersectionvì TypeScript dường như ràng buộc liên hiệp / giao điểm chặt chẽ hơn hàm trả về:
type FunctionUnion = (() => void) | ((p: string) => void);
type FunctionIntersection = (() => void) & ((p: string) => void);
Thử nghiệm:
type SynthesizedFunctionIntersection = UnionToIntersection<FunctionUnion>
Có vẻ tốt!
Hãy cẩn thận rằng nói chung UnionToIntersection<>tiết lộ một số chi tiết về những gì TypeScript nghĩ là một liên minh thực tế. Ví dụ: booleanrõ ràng là được đại diện nội bộ true | false, vì vậy
type Weird = UnionToIntersection<string | number | boolean>
trở thành
type Weird = string & number & true & false
mà trong TS3.6 + được giảm xuống một cách háo hức
type Weird = never
bởi vì không thể có giá trị là string và number và true và false .
Hy vọng rằng sẽ giúp. Chúc may mắn!