/
assets.ts
151 lines (125 loc) · 3.27 KB
/
assets.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
import { Store } from 'vuex'
import { Commit, Dispatch, Context } from './context'
import { Module } from './module'
import { MappedFunction } from './mapper'
interface Class<T> {
new (...args: any[]): T
}
type DeepPartial<T> = T extends Function
? T
: T extends object
? { [K in keyof T]?: DeepPartial<T[K]> }
: T
export function inject<G extends Getters<S>, S>(
Getters: Class<G>,
injection: DeepPartial<G & { state: S; getters: G }>
): G
export function inject<M extends Mutations<S>, S>(
Mutations: Class<M>,
injection: DeepPartial<M & { state: S }>
): M
export function inject<
A extends Actions<S, G, M, A>,
S,
G extends BG<S>,
M extends BM<S>
>(
Actions: Class<A>,
injection: DeepPartial<
A & {
state: S
getters: G
dispatch: any
commit: any
mutations: M
actions: A
}
>
): A
export function inject<T>(
F: Class<T>,
injection: DeepPartial<T> & Record<string, any>
): T {
const proto = F.prototype
const descs: PropertyDescriptorMap = {}
Object.keys(injection).forEach((key) => {
descs[key] = {
configurable: true,
enumerable: true,
writable: true,
value: injection[key],
}
})
return Object.create(proto, descs)
}
export class Getters<S = {}> {
/* @internal */
__ctx__!: Context<Module<S, this, any, any, any>>
$init(_store: Store<any>): void {}
protected get state(): S {
return this.__ctx__.state
}
protected get getters(): this {
return this.__ctx__.getters
}
}
export class Mutations<S = {}> {
/* @internal */
__ctx__!: Context<Module<S, any, any, any, any>>
protected get state(): S {
return this.__ctx__.state
}
}
export class Actions<
S = {},
G extends BG<S> = BG<S>,
M extends BM<S> = BM<S>,
A = {} // We need to specify self action type explicitly to infer dispatch type.
> {
/* @internal */
__ctx__!: Context<Module<S, G, M, any, any>>
$init(_store: Store<any>): void {}
protected get state(): S {
return this.__ctx__.state
}
protected get getters(): G {
return this.__ctx__.getters
}
protected get commit(): Commit<M> {
return this.__ctx__.commit
}
protected get dispatch(): Dispatch<A> {
return this.__ctx__.dispatch
}
/**
* IMPORTANT: Each action type maybe incorrect - return type of all actions should be `Promise<unknown>`
* but the ones under `actions` are same as what you declared in this actions class.
* The reason why we declare the type in such way is to avoid recursive type error.
* See: https://github.com/ktsn/vuex-smart-module/issues/30
*/
protected get actions(): A {
return this.__ctx__.actions as unknown as A
}
protected get mutations(): Committer<M> {
return this.__ctx__.mutations
}
}
export type Committer<M> = {
[K in keyof M]: Payload<M[K]> extends never
? never
: MappedFunction<M[K], void>
}
export type Dispatcher<A> = {
[K in keyof A]: Payload<A[K]> extends never
? never
: MappedFunction<A[K], Promise<unknown>>
}
// Type aliases for internal use
export type BG<S> = Getters<S>
export type BM<S> = Mutations<S>
export type BA<S, G extends BG<S>, M extends BM<S>> = Actions<S, G, M>
export type Payload<T> = T extends (payload?: infer P) => any
? P | undefined
: T extends (payload: infer P) => any
? P
: never