Skip to content

Commit 623c526

Browse files
committed
Use keyof to improve type inference in helpers
1 parent 2f700ac commit 623c526

File tree

2 files changed

+50
-22
lines changed

2 files changed

+50
-22
lines changed

types/helpers.d.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,47 @@
11
import Vue from 'vue';
22
import { Dispatch, Commit } from './index';
33

4-
type Dictionary<T> = { [key: string]: T };
4+
type CompleteObject = { [key: string]: string };
55
type Computed = () => any;
66
type MutationMethod = (...args: any[]) => void;
77
type ActionMethod = (...args: any[]) => Promise<any>;
88

99
interface Mapper<R> {
10-
(map: string[]): Dictionary<R>;
11-
(map: Dictionary<string>): Dictionary<R>;
10+
<T extends CompleteObject, K extends keyof T>(map: K[]): { [key in K]: R };
11+
<T extends CompleteObject, K extends keyof T>(map: { [key in K]: string }): { [key in K]: R };
1212
}
1313

1414
interface MapperWithNamespace<R> {
15-
(namespace: string, map: string[]): Dictionary<R>;
16-
(namespace: string, map: Dictionary<string>): Dictionary<R>;
15+
<T extends CompleteObject, K extends keyof T>(namespace: string, map: K[]): { [key in K]: R };
16+
<T extends CompleteObject, K extends keyof T>(namespace: string, map: { [key in K]: string }): { [key in K]: R };
1717
}
1818

19+
type MappingFunction<F> = (this: typeof Vue, fn: F, ...args: any[]) => any
20+
1921
interface FunctionMapper<F, R> {
20-
(map: Dictionary<(this: typeof Vue, fn: F, ...args: any[]) => any>): Dictionary<R>;
22+
<T extends CompleteObject, K extends keyof T>(map: { [key in K]: MappingFunction<F> }): { [key in K]: R };
2123
}
2224

2325
interface FunctionMapperWithNamespace<F, R> {
24-
(
26+
<T extends CompleteObject, K extends keyof T>(
2527
namespace: string,
26-
map: Dictionary<(this: typeof Vue, fn: F, ...args: any[]) => any>
27-
): Dictionary<R>;
28+
map: { [key in K]: MappingFunction<F> }
29+
): { [key in K]: R };
2830
}
2931

32+
type StateMappingFunction<S> = (this: typeof Vue, state: S, getters: any) => any
33+
3034
interface MapperForState {
31-
<S>(
32-
map: Dictionary<(this: typeof Vue, state: S, getters: any) => any>
33-
): Dictionary<Computed>;
35+
<S, T extends CompleteObject, K extends keyof T>(
36+
map: { [key in K]: StateMappingFunction<S> }
37+
): { [key in K]: Computed };
3438
}
3539

3640
interface MapperForStateWithNamespace {
37-
<S>(
41+
<S, T extends CompleteObject, K extends keyof T>(
3842
namespace: string,
39-
map: Dictionary<(this: typeof Vue, state: S, getters: any) => any>
40-
): Dictionary<Computed>;
43+
map: { [key in K]: StateMappingFunction<S> }
44+
): { [key in K]: Computed };
4145
}
4246

4347
interface NamespacedMappers {

types/test/helpers.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import {
55
mapGetters,
66
mapActions,
77
mapMutations,
8-
createNamespacedHelpers
8+
createNamespacedHelpers,
9+
Commit,
10+
Dispatch
911
} from "../index";
1012

1113
const helpers = createNamespacedHelpers('foo');
@@ -62,7 +64,7 @@ new Vue({
6264
h: "h"
6365
}),
6466
mapActions({
65-
g (dispatch, a: string, b: number, c: boolean): void {
67+
g (dispatch: Dispatch, a: string, b: number, c: boolean): void {
6668
dispatch('g', { a, b, c })
6769
dispatch({
6870
type: 'g',
@@ -77,7 +79,7 @@ new Vue({
7779
h: "h"
7880
}),
7981
mapActions('foo', {
80-
g (dispatch, a: string, b: number, c: boolean): void {
82+
g (dispatch: Dispatch, a: string, b: number, c: boolean): void {
8183
dispatch('g', { a, b, c })
8284
dispatch({
8385
type: 'g',
@@ -93,7 +95,7 @@ new Vue({
9395
j: "j"
9496
}),
9597
mapMutations({
96-
i (commit, a: string, b: number, c: boolean): void {
98+
i (commit: Commit, a: string, b: number, c: boolean): void {
9799
commit('i', { a, b, c })
98100
commit({
99101
type: 'i',
@@ -108,7 +110,7 @@ new Vue({
108110
j: "j"
109111
}),
110112
mapMutations('foo', {
111-
i (commit, a: string, b: number, c: boolean): void {
113+
i (commit: Commit, a: string, b: number, c: boolean): void {
112114
commit('i', { a, b, c })
113115
commit({
114116
type: 'i',
@@ -124,7 +126,7 @@ new Vue({
124126
m: "m"
125127
}),
126128
helpers.mapActions({
127-
m (dispatch, value: string) {
129+
m (dispatch: Dispatch, value: string) {
128130
dispatch('m', value)
129131
}
130132
}),
@@ -134,13 +136,35 @@ new Vue({
134136
n: "n"
135137
}),
136138
helpers.mapMutations({
137-
n (commit, value: string) {
139+
n (commit: Commit, value: string) {
138140
commit('m', value)
139141
}
140142
}),
143+
helpers.mapMutations({
144+
n: "n",
145+
m: "m"
146+
}),
141147

142148
{
143149
otherMethod () {}
144150
}
145151
)
146152
});
153+
154+
const actions = mapActions({
155+
mAlias: "m"
156+
})
157+
158+
actions.mAlias()
159+
160+
const actionsNamespaced = mapActions('namespace', {
161+
mAlias: "m"
162+
})
163+
164+
actionsNamespaced.mAlias()
165+
166+
const actionsNamespaced2 = helpers.mapActions({
167+
mAlias: "m"
168+
})
169+
170+
actionsNamespaced2.mAlias()

0 commit comments

Comments
 (0)