UNPKG

1.88 kBPlain TextView Raw
1// This entire implementation courtesy of Anders Hjelsberg:
2// https://github.com/microsoft/TypeScript/pull/50831#issuecomment-1253830522
3
4import { ReverseHead, ReverseTail } from '../types'
5
6type UnknownFunction = (...args: any[]) => any
7
8type LongestTuple<T> = T extends [infer U extends unknown[]]
9 ? U
10 : T extends [infer U, ...infer R extends unknown[][]]
11 ? MostProperties<U, LongestTuple<R>>
12 : never
13
14type MostProperties<T, U> = keyof U extends keyof T ? T : U
15
16type ElementAt<T, N extends keyof any> = N extends keyof T ? T[N] : unknown
17
18type ElementsAt<T, N extends keyof any> = {
19 [K in keyof T]: ElementAt<T[K], N>
20}
21
22type Intersect<T extends readonly unknown[]> = T extends []
23 ? unknown
24 : T extends [infer H, ...infer T]
25 ? H & Intersect<T>
26 : T[number]
27
28type MergeTuples<T, L extends unknown[] = LongestTuple<T>> = {
29 [K in keyof L]: Intersect<
30 ElementsAt<T, K> extends readonly unknown[] ? ElementsAt<T, K> : never
31 >
32}
33
34type ExtractParameters<T extends readonly UnknownFunction[]> = {
35 [K in keyof T]: Parameters<T[K]>
36}
37
38export type MergeParameters<T extends readonly UnknownFunction[]> =
39 '0' extends keyof T
40 ? MergeTuples<MakeRestExplicit<ExtractParameters<T>>>
41 : Parameters<T[number]>
42
43type HasRest<S extends readonly unknown[]> = number extends S['length']
44 ? true
45 : false
46
47type HasExplicit<S extends readonly unknown[]> = '0' extends keyof S
48 ? true
49 : false
50
51type HasCombined<S extends readonly unknown[]> = true extends HasExplicit<S> &
52 HasRest<S>
53 ? true
54 : false
55
56type MakeRestExplicit<T extends readonly unknown[][]> =
57 true extends HasCombined<T>
58 ? [
59 ...ReverseTail<T>,
60 ReverseHead<T> extends readonly unknown[]
61 ? ReverseHead<T>[number]
62 : never
63 ]
64 : true extends HasRest<T>
65 ? [...T]
66 : T