UNPKG

3.86 kBPlain TextView Raw
1import type { Middleware, StoreEnhancer } 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/**
70 * Convert a Union type `(A|B)` to an intersection type `(A&B)`
71 */
72export type UnionToIntersection<U> = (
73 U extends any ? (k: U) => void : never
74) extends (k: infer I) => void
75 ? I
76 : never
77
78// Appears to have a convenient side effect of ignoring `never` even if that's not what you specified
79export type ExcludeFromTuple<T, E, Acc extends unknown[] = []> = T extends [
80 infer Head,
81 ...infer Tail
82]
83 ? ExcludeFromTuple<Tail, E, [...Acc, ...([Head] extends [E] ? [] : [Head])]>
84 : Acc
85
86type ExtractDispatchFromMiddlewareTuple<
87 MiddlewareTuple extends any[],
88 Acc extends {}
89> = MiddlewareTuple extends [infer Head, ...infer Tail]
90 ? ExtractDispatchFromMiddlewareTuple<
91 Tail,
92 Acc & (Head extends Middleware<infer D> ? IsAny<D, {}, D> : {})
93 >
94 : Acc
95
96export type ExtractDispatchExtensions<M> = M extends MiddlewareArray<
97 infer MiddlewareTuple
98>
99 ? ExtractDispatchFromMiddlewareTuple<MiddlewareTuple, {}>
100 : M extends ReadonlyArray<Middleware>
101 ? ExtractDispatchFromMiddlewareTuple<[...M], {}>
102 : never
103
104export type ExtractStoreExtensions<E> = E extends any[]
105 ? UnionToIntersection<E[number] extends StoreEnhancer<infer Ext> ? Ext extends {} ? Ext : {} : {}>
106 : {}
107
108/**
109 * Helper type. Passes T out again, but boxes it in a way that it cannot
110 * "widen" the type by accident if it is a generic that should be inferred
111 * from elsewhere.
112 *
113 * @internal
114 */
115export type NoInfer<T> = [T][T extends any ? 0 : never]
116
117export type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
118
119export interface TypeGuard<T> {
120 (value: any): value is T
121}
122
123export interface HasMatchFunction<T> {
124 match: TypeGuard<T>
125}
126
127export const hasMatchFunction = <T>(
128 v: Matcher<T>
129): v is HasMatchFunction<T> => {
130 return v && typeof (v as HasMatchFunction<T>).match === 'function'
131}
132
133/** @public */
134export type Matcher<T> = HasMatchFunction<T> | TypeGuard<T>
135
136/** @public */
137export type ActionFromMatcher<M extends Matcher<any>> = M extends Matcher<
138 infer T
139>
140 ? T
141 : never
142
143export type Id<T> = { [K in keyof T]: T[K] } & {}