Types VUEX store
Goal 1
Бачити автокомпліт стора, а не бред від IDE

Оголошуємо свій Store
import { Store } from 'vuex'
import { iStoreState, iThread } from './types'
declare module 'vue/types/vue' {
interface Vue {
$store: Store<iStoreState> & {
state: iStoreState
getters: {
isAuthenticated: boolean
activeThread: iThread | undefined
}
}
}
}видалити $store: Store<any> з node_modules/vuex/types/vue.d.ts
Результат


Goal 2
Було б круто коли $store.commit перевіряв вхідні параметри
Оголошуємо типи для Store
// file path: types/Store.ts
import { iSearchUser } from 'social-api'
import { iFemaleSimple, iProfile, iDictionary, iUser } from '@/types'
export type MutationTypes = {
COMMON_ADD_DICTIONARY: iDictionary
COMMON_ADD_FEMALES: iFemaleSimple[]
COMMON_INIT_USER: iUser
COMMON_CLEAR: never
COMMON_FEMALE_ONLINE: { ids: number[], status: boolean }
COMMON_TOGGLE_SITE_BAR: boolean
PROFILE_ADD: (iProfile | iSearchUser)[]
PROFILE_CREATE_DEFAULT: number
}
Типізуємо commit
import { Store, CommitOptions } from 'vuex'
import { iStoreState, iThread, MutationTypes } from './types'
declare module 'vue/types/vue' {
interface Vue {
$store: Store<iStoreState> & {
state: iStoreState
getters: {
isAuthenticated: boolean
activeThread: iThread | undefined
}
commit<key extends keyof MutationTypes>(
type: key,
payload?: MutationTypes[key],
options?: CommitOptions,
): void
}
}
}Ніфіга не працює
// file node_modules/types/index.ts
export interface Dispatch {
(type: string, payload?: any, options?: DispatchOptions): Promise<any>;
<P extends Payload>(payloadWithType: P, options?: DispatchOptions): Promise<any>;
}
export interface Commit {
(type: string, payload?: any, options?: CommitOptions): void;
<P extends Payload>(payloadWithType: P, options?: CommitOptions): void;
}Той момент коли наявна типізація шкідлива, потрібно видаляти
Result


Але без аргументів не має помилки, а він в даному випадку обов'язковий
В компонентах порядок, але...

Додаємо типи до видаленого інтерфейса
// file: shims.d.ts
declare module 'vuex/types/index' {
interface Commit {
<T extends keyof Store.MutationTypes>(
name: T,
payload: Store.MutationTypes[T],
options?: CommitOptions,
): void
}
}
А як же об'єктна нотація?
this.$store.commit({
type: 'COMMON_FEMALE_ONLINE',
ids: this.id,
status: 'error',
})Автоматизація видалення поганих типів
const fs = require('fs')
const pathVuex = './node_modules/vuex/types/index.d.ts'
const pathVue = './node_modules/vuex/types/vue.d.ts'
function exitIfErr(err) {
if (err) {
process.exit(1)
}
}
fs.readFile(pathVuex, 'utf8', (err, data) => {
exitIfErr(err)
const res = data
.replace(/(\(type: string, payload\?: any, options\?)/g, '// $1')
.replace(/(<P extends Payload>\(payloadWithType: P)/g, '// $1')
fs.writeFile(pathVuex, res, exitIfErr)
})
fs.readFile(pathVue, 'utf8', (err, data) => {
exitIfErr(err)
const res = data.replace(/(\$store: Store<any>;)/g, '// $1')
fs.writeFile(pathVue, res, exitIfErr)
})
Vuex types legacy code
By Kolya Koval
Vuex types legacy code
- 213