forked from reduxjs/react-redux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.ts
277 lines (255 loc) · 8.65 KB
/
types.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/* eslint-disable no-unused-vars */
// TODO Ignoring all unused variables for now
import {
ClassAttributes,
Component,
ComponentClass,
ComponentType,
StatelessComponent,
Context,
NamedExoticComponent,
} from 'react'
import { Action, ActionCreator, AnyAction, Dispatch, Store } from 'redux'
// import hoistNonReactStatics = require('hoist-non-react-statics');
import type { NonReactStatics } from 'hoist-non-react-statics'
export type FixTypeLater = any
export type EqualityFn<T> = (a: T | undefined, b: T | undefined) => boolean
/**
* This interface can be augmented by users to add default types for the root state when
* using `react-redux`.
* Use module augmentation to append your own type definition in a your_custom_type.d.ts file.
* https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
*/
// tslint:disable-next-line:no-empty-interface
export interface DefaultRootState {}
export type AnyIfEmpty<T extends object> = keyof T extends never ? any : T
export type RootStateOrAny = AnyIfEmpty<DefaultRootState>
// Omit taken from https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
export type DistributiveOmit<T, K extends keyof T> = T extends unknown
? Omit<T, K>
: never
export interface DispatchProp<A extends Action = AnyAction> {
dispatch: Dispatch<A>
}
export type AdvancedComponentDecorator<TProps, TOwnProps> = (
component: ComponentType<TProps>
) => ComponentType<TOwnProps>
/**
* A property P will be present if:
* - it is present in DecorationTargetProps
*
* Its value will be dependent on the following conditions
* - if property P is present in InjectedProps and its definition extends the definition
* in DecorationTargetProps, then its definition will be that of DecorationTargetProps[P]
* - if property P is not present in InjectedProps then its definition will be that of
* DecorationTargetProps[P]
* - if property P is present in InjectedProps but does not extend the
* DecorationTargetProps[P] definition, its definition will be that of InjectedProps[P]
*/
export type Matching<InjectedProps, DecorationTargetProps> = {
[P in keyof DecorationTargetProps]: P extends keyof InjectedProps
? InjectedProps[P] extends DecorationTargetProps[P]
? DecorationTargetProps[P]
: InjectedProps[P]
: DecorationTargetProps[P]
}
/**
* a property P will be present if :
* - it is present in both DecorationTargetProps and InjectedProps
* - InjectedProps[P] can satisfy DecorationTargetProps[P]
* ie: decorated component can accept more types than decorator is injecting
*
* For decoration, inject props or ownProps are all optionally
* required by the decorated (right hand side) component.
* But any property required by the decorated component must be satisfied by the injected property.
*/
export type Shared<InjectedProps, DecorationTargetProps> = {
[P in Extract<
keyof InjectedProps,
keyof DecorationTargetProps
>]?: InjectedProps[P] extends DecorationTargetProps[P]
? DecorationTargetProps[P]
: never
}
// Infers prop type from component C
export type GetProps<C> = C extends ComponentType<infer P>
? C extends ComponentClass<P>
? ClassAttributes<InstanceType<C>> & P
: P
: never
// Applies LibraryManagedAttributes (proper handling of defaultProps
// and propTypes), as well as defines WrappedComponent.
export type ConnectedComponent<
C extends ComponentType<any>,
P
> = ComponentType<P> &
NonReactStatics<C> & {
WrappedComponent: C
}
// Injects props and removes them from the prop requirements.
// Will not pass through the injected props if they are passed in during
// render. Also adds new prop requirements from TNeedsProps.
// Uses distributive omit to preserve discriminated unions part of original prop type
export type InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps> = <
C extends ComponentType<Matching<TInjectedProps, GetProps<C>>>
>(
component: C
) => ConnectedComponent<
C,
DistributiveOmit<GetProps<C>, keyof Shared<TInjectedProps, GetProps<C>>> &
TNeedsProps
>
// Injects props and removes them from the prop requirements.
// Will not pass through the injected props if they are passed in during
// render.
export type InferableComponentEnhancer<TInjectedProps> =
InferableComponentEnhancerWithProps<TInjectedProps, {}>
export type InferThunkActionCreatorType<
TActionCreator extends (...args: any[]) => any
> = TActionCreator extends (
...args: infer TParams
) => (...args: any[]) => infer TReturn
? (...args: TParams) => TReturn
: TActionCreator
export type HandleThunkActionCreator<TActionCreator> = TActionCreator extends (
...args: any[]
) => any
? InferThunkActionCreatorType<TActionCreator>
: TActionCreator
// redux-thunk middleware returns thunk's return value from dispatch call
// https://github.com/reduxjs/redux-thunk#composition
export type ResolveThunks<TDispatchProps> = TDispatchProps extends {
[key: string]: any
}
? {
[C in keyof TDispatchProps]: HandleThunkActionCreator<TDispatchProps[C]>
}
: TDispatchProps
// the conditional type is to support TypeScript 3.0, which does not support mapping over tuples and arrays;
// once the typings are updated to at least TypeScript 3.1, a simple mapped type can replace this mess
export type ResolveArrayThunks<TDispatchProps extends ReadonlyArray<any>> =
TDispatchProps extends [
infer A1,
infer A2,
infer A3,
infer A4,
infer A5,
infer A6,
infer A7,
infer A8,
infer A9
]
? [
HandleThunkActionCreator<A1>,
HandleThunkActionCreator<A2>,
HandleThunkActionCreator<A3>,
HandleThunkActionCreator<A4>,
HandleThunkActionCreator<A5>,
HandleThunkActionCreator<A6>,
HandleThunkActionCreator<A7>,
HandleThunkActionCreator<A8>,
HandleThunkActionCreator<A9>
]
: TDispatchProps extends [
infer A1,
infer A2,
infer A3,
infer A4,
infer A5,
infer A6,
infer A7,
infer A8
]
? [
HandleThunkActionCreator<A1>,
HandleThunkActionCreator<A2>,
HandleThunkActionCreator<A3>,
HandleThunkActionCreator<A4>,
HandleThunkActionCreator<A5>,
HandleThunkActionCreator<A6>,
HandleThunkActionCreator<A7>,
HandleThunkActionCreator<A8>
]
: TDispatchProps extends [
infer A1,
infer A2,
infer A3,
infer A4,
infer A5,
infer A6,
infer A7
]
? [
HandleThunkActionCreator<A1>,
HandleThunkActionCreator<A2>,
HandleThunkActionCreator<A3>,
HandleThunkActionCreator<A4>,
HandleThunkActionCreator<A5>,
HandleThunkActionCreator<A6>,
HandleThunkActionCreator<A7>
]
: TDispatchProps extends [
infer A1,
infer A2,
infer A3,
infer A4,
infer A5,
infer A6
]
? [
HandleThunkActionCreator<A1>,
HandleThunkActionCreator<A2>,
HandleThunkActionCreator<A3>,
HandleThunkActionCreator<A4>,
HandleThunkActionCreator<A5>,
HandleThunkActionCreator<A6>
]
: TDispatchProps extends [infer A1, infer A2, infer A3, infer A4, infer A5]
? [
HandleThunkActionCreator<A1>,
HandleThunkActionCreator<A2>,
HandleThunkActionCreator<A3>,
HandleThunkActionCreator<A4>,
HandleThunkActionCreator<A5>
]
: TDispatchProps extends [infer A1, infer A2, infer A3, infer A4]
? [
HandleThunkActionCreator<A1>,
HandleThunkActionCreator<A2>,
HandleThunkActionCreator<A3>,
HandleThunkActionCreator<A4>
]
: TDispatchProps extends [infer A1, infer A2, infer A3]
? [
HandleThunkActionCreator<A1>,
HandleThunkActionCreator<A2>,
HandleThunkActionCreator<A3>
]
: TDispatchProps extends [infer A1, infer A2]
? [HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>]
: TDispatchProps extends [infer A1]
? [HandleThunkActionCreator<A1>]
: TDispatchProps extends Array<infer A>
? Array<HandleThunkActionCreator<A>>
: TDispatchProps extends ReadonlyArray<infer A>
? ReadonlyArray<HandleThunkActionCreator<A>>
: never
/**
* This interface allows you to easily create a hook that is properly typed for your
* store's root state.
*
* @example
*
* interface RootState {
* property: string;
* }
*
* const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;
*/
export interface TypedUseSelectorHook<TState> {
<TSelected>(
selector: (state: TState) => TSelected,
equalityFn?: EqualityFn<TSelected>
): TSelected
}