You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Vuex mapGetters时如何解决TypeScript报错问题?

解决Vuex mapGetters在TypeScript中类型不识别的问题

这个问题确实是Vue + TypeScript组合开发中很常见的痛点——mapGetters注入的属性没办法被TypeScript自动推断,导致访问this.navCollapsed时抛出类型错误。不用mapGetters确实能绕开,但完全没必要,下面给你几个更优雅的解决方案:

方案1:手动声明计算属性的类型

你可以通过定义一个接口来描述组件的计算属性,然后在Vue.extend里指定这个类型,让TypeScript能识别到mapGetters注入的属性:

import Vue from 'vue';
import { mapActions, mapGetters } from 'vuex';

// 定义组件计算属性的类型
interface ComponentComputed {
  navCollapsed: boolean;
  minimizerIconClass: string;
}

export default Vue.extend({
  computed: {
    ...mapGetters('ui', ['navCollapsed']),
    minimizerIconClass(): string {
      return `fa${this.navCollapsed ? '' : 'r'} fa-window-maximize`;
    },
  } as ComponentComputed, // 断言计算属性的类型,让TS识别注入的getter
})

这样TypeScript就能明确知道this.navCollapsed是存在的,而且类型是boolean

方案2:使用Vuex的类型辅助工具(推荐)

如果你的Vuex store已经做了类型定义,那可以利用类型映射让mapGetters获得正确的类型推断,这也是更符合TypeScript最佳实践的方式。

首先确保你的store模块有明确的类型:

// store/modules/ui.ts
export interface UiState {
  navCollapsed: boolean;
}

export const state: UiState = {
  navCollapsed: false,
};

export const getters = {
  navCollapsed: (state: UiState) => state.navCollapsed,
};

然后在组件里,自定义一个带类型约束的mapGetters方法:

import Vue from 'vue';
import { mapGetters } from 'vuex';
import { UiState } from '@/store/modules/ui';

// 定义模块getters的类型
type UiGetters = {
  navCollapsed: boolean;
};

// 给mapGetters加上模块和类型约束
const mapUiGetters = mapGetters<'ui', keyof UiGetters>('ui');

export default Vue.extend({
  computed: {
    ...mapUiGetters(['navCollapsed']),
    minimizerIconClass(): string {
      return `fa${this.navCollapsed ? '' : 'r'} fa-window-maximize`;
    },
  },
})

这种方式能让类型推断更精准,后续修改store的getter时,组件也能同步获得类型提示。

方案3:直接通过$store访问getters

如果上面的方法你觉得麻烦,也可以不使用mapGetters,而是直接通过this.$store.getters['ui/navCollapsed']访问,只要你的store做了全局类型定义,TypeScript就能识别这个属性:

import Vue from 'vue';
import { mapActions } from 'vuex';

export default Vue.extend({
  computed: {
    navCollapsed(): boolean {
      return this.$store.getters['ui/navCollapsed'];
    },
    minimizerIconClass(): string {
      return `fa${this.navCollapsed ? '' : 'r'} fa-window-maximize`;
    },
  },
})

这种方式虽然没有mapGetters简洁,但胜在类型安全,不需要额外的类型声明。


内容的提问来源于stack exchange,提问作者ffxsam

火山引擎 最新活动