UNPKG

3.61 kBPlain TextView Raw
1import type { Middleware } from 'redux'
2import type { MiddlewareArray } from './utils'
3
4/**
5 * return True if T is `any`, otherwise return False
6 * taken from https://github.com/joonhocho/tsdef
7 *
8 * @internal
9 */
10export type IsAny<T, True, False = never> =
11 // test if we are going the left AND right path in the condition
12 true | false extends (T extends never ? true : false) ? True : False
13
14/**
15 * return True if T is `unknown`, otherwise return False
16 * taken from https://github.com/joonhocho/tsdef
17 *
18 * @internal
19 */
20export type IsUnknown<T, True, False = never> = unknown extends T
21 ? IsAny<T, False, True>
22 : False
23
24export type FallbackIfUnknown<T, Fallback> = IsUnknown<T, Fallback, T>
25
26/**
27 * @internal
28 */
29export type IfMaybeUndefined<P, True, False> = [undefined] extends [P]
30 ? True
31 : False
32
33/**
34 * @internal
35 */
36export type IfVoid<P, True, False> = [void] extends [P] ? True : False
37
38/**
39 * @internal
40 */
41export type IsEmptyObj<T, True, False = never> = T extends any
42 ? keyof T extends never
43 ? IsUnknown<T, False, IfMaybeUndefined<T, False, IfVoid<T, False, True>>>
44 : False
45 : never
46
47/**
48 * returns True if TS version is above 3.5, False if below.
49 * uses feature detection to detect TS version >= 3.5
50 * * versions below 3.5 will return `{}` for unresolvable interference
51 * * versions above will return `unknown`
52 *
53 * @internal
54 */
55export type AtLeastTS35<True, False> = [True, False][IsUnknown<
56 ReturnType<<T>() => T>,
57 0,
58 1
59>]
60
61/**
62 * @internal
63 */
64export type IsUnknownOrNonInferrable<T, True, False> = AtLeastTS35<
65 IsUnknown<T, True, False>,
66 IsEmptyObj<T, True, IsUnknown<T, True, False>>
67>
68
69// Appears to have a convenient side effect of ignoring `never` even if that's not what you specified
70export type ExcludeFromTuple<T, E, Acc extends unknown[] = []> = T extends [
71 infer Head,
72 ...infer Tail
73]
74 ? ExcludeFromTuple<Tail, E, [...Acc, ...([Head] extends [E] ? [] : [Head])]>
75 : Acc
76
77type ExtractDispatchFromMiddlewareTuple<
78 MiddlewareTuple extends any[],
79 Acc extends {}
80> = MiddlewareTuple extends [infer Head, ...infer Tail]
81 ? ExtractDispatchFromMiddlewareTuple<
82 Tail,
83 Acc & (Head extends Middleware<infer D, any> ? IsAny<D, {}, D> : {})
84 >
85 : Acc
86
87export type ExtractDispatchExtensions<M> = M extends MiddlewareArray<
88 infer MiddlewareTuple
89>
90 ? ExtractDispatchFromMiddlewareTuple<MiddlewareTuple, {}>
91 : M extends Middleware[]
92 ? ExtractDispatchFromMiddlewareTuple<[...M], {}>
93 : never
94
95/**
96 * Convert a Union type `(A|B)` to an intersection type `(A&B)`
97 */
98export type UnionToIntersection<U> = (
99 U extends any ? (k: U) => void : never
100) extends (k: infer I) => void
101 ? I
102 : never
103
104/**
105 * Helper type. Passes T out again, but boxes it in a way that it cannot
106 * "widen" the type by accident if it is a generic that should be inferred
107 * from elsewhere.
108 *
109 * @internal
110 */
111export type NoInfer<T> = [T][T extends any ? 0 : never]
112
113export type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
114
115export interface TypeGuard<T> {
116 (value: any): value is T
117}
118
119export interface HasMatchFunction<T> {
120 match: TypeGuard<T>
121}
122
123export const hasMatchFunction = <T>(
124 v: Matcher<T>
125): v is HasMatchFunction<T> => {
126 return v && typeof (v as HasMatchFunction<T>).match === 'function'
127}
128
129/** @public */
130export type Matcher<T> = HasMatchFunction<T> | TypeGuard<T>
131
132/** @public */
133export type ActionFromMatcher<M extends Matcher<any>> = M extends Matcher<
134 infer T
135>
136 ? T
137 : never