1.1.1 • Published 3 years ago

vuex-with-type v1.1.1

Weekly downloads
-
License
ISC
Repository
-
Last release
3 years ago

作用

vuex-with-type是为了解决vuex4以下版本在typescript编写时无法正确推断出类型的问题,已支持嵌套的模块推断。

效果

State

state.gif

Commit

commit.gif

Dispatch

dispatch.gif

原理

vuex4以下不能正确推断出类型的本质原因是因为vuex官方的声明文件在合并Vue时将$store的类型推断写为了Store<any>,这导致我们后续的声明合并 都无法收窄类型,因此state的类型为any,commit等类型也无法准确推断。我的方法很简单,读取node_modules中vuex的这个声明文件,将多余的部分去掉, 然后自动生成可以精确推断出state与commit的声明文件。

安装

npm install vuex-with-type

使用方法

npx vwt init

全局使用vwt命令:

  • vwt handbook 👉 查看所有命令说明
  • vwt config 👉 生成配置文件 以配置文件的形式进行源码生成
  • vwt init 👉 初始化并生成声明文件 如果有config命令生成的文件,则会优先使用它

示例

  • store/index.ts:
import Vue from 'vue'
import Vuex, { Commit } from 'vuex'
import { isOwnKey, NonNeverState, GetState, GetMutationKeyParamMap, GetActionKeyParamMap } from "vuex-with-type";

Vue.use(Vuex)

const state = {
  token: "",
  openId: "",
  name: "",
  appId: "1"
}

// 将vuex store独立出来
const storeOptions = {
  state,
  mutations: {
    SET_STATE(s: NonNeverState<typeof state>, obj: Partial<NonNeverState<typeof state>>) {
      for (const key in obj) {
        if (isOwnKey(key, obj)) {
          s[key] = obj[key];
        }
      }
    },
    SET_NAME(s: NonNeverState<typeof state>, v: string) {
      s.name = v;
    }
  },
  actions: {
    SET_ASYNC_STATE({ commit }: { commit: Commit }, obj: Partial<NonNeverState<typeof state>>) {
      return new Promise(resolve=> {
        setTimeout(()=> {
          commit("SET_STATE", obj);
          resolve(obj);
        });
      });
    }
  },
  modules: {
    modOne: { ... },
    modTwo: { ... }
  }
};

/** TState TMutation TAction(如果有的话) 必须要导出,当然你可以不叫这个名字,但必须在
 *	自动生成的声明文件中对应
 */
export type TState = NonNeverState<GetState<typeof storeOptions>>

/**
 * @description mutation类型,能够推断出嵌套的modules:
 * {
 *    SET_XXX: typeof second param;
 *    module/SET_XX: typeof second param;
 *    module/moduleSon/SET_X: typeof second param
 * }
 */
export type TMutation = GetMutationKeyParamMap<typeof storeOptions>;

export type TAction = GetActionKeyParamMap<typeof storeOptions>;

const store = new Vuex.Store<TState>(storeOptions);

export default store;

effect

vuex-with-type is to solve the problem that vuex4 and lower versions cannot correctly infer the type when writing typescript. For now, I only wrote the type inference of state and mutation for the time being.

prieiple

The essential reason why the type cannot be correctly inferred under vuex4 is because the official vuex declaration file writes the type inference of $store as Store<any> when merging Vue, which leads to the merger of our subsequent declarations Neither can narrow the type, so the type of state is any, and the type of commit cannot be accurately inferred. My method is very simple. Reading this declaration file of vuex in node_modules then delete extra part.Then generate a declaration file that can accurately infer the state and commit automatically.

install

npm install vuex-with-type

usage

npx vwt init

Use the vwt command globally:

  • vwt handbook 👉 View all command descriptions
  • vwt config 👉 Generate configuration file
  • vwt init 👉 Initialize and generate a declaration file. If there is a file generated by the config command, it will be used first

if everything is ok, you can get correct type now.

This is my first time writing an open source library, Sorry for not doing well.

1.1.1

3 years ago

1.1.0

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago