Я пытаюсь сделать магазин Vuex дружественным к Typescript. Я строю магазин, как объяснил здесь. Однако, когда я обращаюсь к this.$store из компонента, это тип Store<any>.
Я не мог понять, как изменить его так, чтобы он по умолчанию был Store<MyState>, не требуя каждый раз приведения.






Вы можете объявить свойство в своем компоненте, чтобы машинописный текст применил типизацию. Я постоянно использую это для $refs, но он работает и для $store. Вам не нужно ничего делать с имуществом, кроме как пометить его значком! , чтобы сообщить транспиллеру, что vue установит переменную за вас.
$store!: Store<StoreStateType>;
Другая альтернатива, которую я использую, - использовать помощники компонентов MapState или MapGetters. Они создают для вас свойства, чтобы вы могли использовать их в шаблоне. Пример:
@Component({
computed: mapState({
userFullName: (state: any) => state.user.fullName,
userEmail: (state: any) => state.user.email
})
})
Не забудьте импортировать Store, ваш класс состояния vuex и любой помощник, который вы используете import { Store, mapState } from "vuex";.
К сожалению, невозможно переопределить тип Store<any>, который определяется типами VueX, более конкретным типом. Лучшее, что я мог придумать, - это добавить второе поле, которое возвращает $store, но правильно набранное, чтобы вам не приходилось везде использовать приведение типов или объявлять его во всех ваших компонентах:
import { Store } from "vuex";
// Type the $tstore properly, which is the same as $store but properly typed.
// Unfortunately you cannot override the Store<any> type.
declare module "vue/types/vue" {
interface Vue {
$tstore: Store<State>;
}
}
// Set $tstore to be a getter that simply returns $store.
Object.defineProperty(Vue.prototype, "$tstore", {
get: function() {
return this.$store as Store<State>;
},
enumerable: true,
});
Если кто-то сталкивается с этим - мы обошли эту проблему, переопределив тип, возвращаемый конструктором -
import Vue, { VueConstructor } from 'vue'
import { Store } from 'vuex'
import { RootState } from '@/store/types'
abstract class VueStrongClass extends Vue {
public $store!: Store<RootState>
}
const VueStrong = Vue as VueConstructor<VueStrongClass>;
export default VueStrong;
а потом мы просто
export default VueStrong.extend({
name: 'name',
components: {
componentA,
componentB,
},
что позволяет нам правильно печатать:
methods: {
sessionStarted(): Boolean | undefined {
return this.$store.state.sessionState?.session.started;
},
@maembe К сожалению, я так не думаю - вы могли бы по-настоящему развлечься с перечислением и некоторыми дженериками, но это хуже, чем просто кастинг вручную. знак равно
Ни один из ответов меня не удовлетворил. Я покопался и нашел эту жемчужину. Внутри моего файла store.ts я просто добавляю:
declare module "@vue/runtime-core" {
interface ComponentCustomProperties {
$store: Store<State>;
}
}
Так это выглядит примерно так:
//store.ts
import { createStore, Store } from "vuex";
import { CustomTool, CustomListType } from "custom";
export type State = {
tool: CustomTool
list: CustomListType | null
};
export default createStore({
state: {
tool: CustomTool.Empty
list: null,
} as State,
mutations: {},
actions: {},
modules: {}
};
declare module "@vue/runtime-core" {
interface ComponentCustomProperties {
$store: Store<State>;
}
}
Использование vue3 и машинописного текста 4.4.
вы знаете, есть ли способ заставить печатать, чтобы работать с этим. $ store.getters?