使用 TypeScript 的 Vuex 映射函数

Vuex map functions with TypeScript

我的状态(游戏名称空间)有一个界面,如下所示:

interface GameState {
  selectedTab: number;
  timeout: number;
  snackbar: boolean;
  text: string;
  doneTasks: number;
  taskTypes: TaskType[];
  stages: Stage[];
}

我正在尝试使用 mapState 将 'taskTypes' 映射到组件内部,如下所示:

...mapState('game', {
  taskTypes: (state: GameState): TaskType[] => state.taskTypes,
}),

我收到以下错误“'{taskTypes: (state: GameState) => TaskType[];}' 类型的参数不可分配给 'string[]' 类型的参数。”

当将函数的“state”参数类型定义为 'any' 时,它可以编译并工作,所以我尝试在 devtools 中“调试”该函数并查看“state”参数包含什么,它保存我的游戏状态,它具有在 GameState 界面中定义的确切道具。

有谁知道为什么 ts 不让我用正确的类型定义“状态”参数(这是首先定义接口并避免 'any' 的全部目的)

这也行不通:

...mapState({
  taskTypes: ({ state }: Store<GameState>): TaskType[] => state.taskTypes,
}),

有没有人遇到过这样的问题?任何想法如何处理它的最佳实践方法?

mapActions 等也是如此...

更新 我尝试为我的商店和模块提供更好的打字。现在他们是: 总店:

export default new Store<RootState>({
  modules: {
    users,
    game,
  },
});

RootState 为:

export interface RootState {
  game: GameState;
  users: UserState;
}

游戏模块:

type GameActionContext = ActionContext<GameState, RootState>;

const gameModule: Module<GameState, RootState> = {
  namespaced: true,
  state: {
    selectedTab: 0,
    timeout: 5000,
    snackbar: false,
    text: '',
    doneTasks: 0,
    taskTypes: [...],
    stages: [...],
  } as GameState,
  mutations: {/*Mutations*/} as MutationTree<GameState>,
  actions: {/*Actions*/} as ActionTree<GameState, RootState>,
};

export default gameModule;

我正在尝试通过以下方式映射状态对象:

...mapState({
      taskTypes: (state): TaskType[] => state.GameState.taskTypes
})

但我收到错误消息:

(parameter) state: unknown - Object is of type 'unknown'

我通常不得不将对象转换为未知类型,然后转换为实际类型。

您可以尝试这种方法,创建一个像这样的泛型类型,基本上可以使值作为函数使用:

export type Computed<T> = {
    [K in keyof T]: () => T[K];
};

现在您可以在这样的组件中使用它:

...((mapState('auth', ['taskTypes']) as unknown) as Pick<Computed<GameState>, 'taskTypes'>)

现在应该输入 this.taskTypes

发布迄今为止我想出的最佳解决方案(至少代码和键入的代码):

...mapState({
  taskTypes: (state): TaskType[] => (state as RootState).game.taskTypes,
}),

因为 state 将始终等于 RootState,所以对于每个 mapState,转换将始终保持相同。不能说我对这个解决方案完全满意,但现在它似乎是最好的(不需要任何额外的接口/长行的转换类型)

您可以将泛型类型传递给 mapState

...mapState<GameState>('game', {
  taskTypes: (state: GameState): TaskType[] => state.taskTypes,
}),

我在 mapGetters 上收到了相同的错误消息,我设法在 Vue2 组件中正确键入它的方式如下所示:

...(mapGetters("module", ['someGetter']) as {someGetter: () => boolean}),
...(mapState("appModule", ["appIsLoading"]) as {appIsLoading: () => boolean;}),
...(mapMutations("appModule", ["SET_APP_IS_LOADING"]) as {SET_APP_IS_LOADING: (payload: boolean) => void;}),
...(mapActions("appModule", ["extendLockTime"]) as {extendLockTime: () => void;}),

有了这个类型提示,组件内部的类型检查是正确的。