Sfoglia il codice sorgente

Update declaration (#218)

* Update the declaration and its dependency for typings

* Add a test for the declaration

* Add README for the types directory

* Fix test case because of incorrect usage

* Remove deprecated watch API from types

* Update types for 1.0

- middlewares -> plugins
- new method: replaceState, on, once, off and emit

* Add test cases for plugins, replaceState and events

* Fix type of logger plugin
katashin 8 anni fa
parent
commit
acbb2ddebf
9 ha cambiato i file con 334 aggiunte e 32 eliminazioni
  1. 2 0
      .gitignore
  2. 0 20
      index.d.ts
  3. 0 12
      tsconfig.json
  4. 7 0
      types/README.md
  5. 95 0
      types/index.d.ts
  6. 200 0
      types/test/index.ts
  7. 12 0
      types/test/tsconfig.json
  8. 11 0
      types/tsconfig.json
  9. 7 0
      types/typings.json

+ 2 - 0
.gitignore

@@ -5,3 +5,5 @@ lib
 docs/_book
 logger.js
 examples/**/build.js
+types/typings
+types/test/*.js

+ 0 - 20
index.d.ts

@@ -1,20 +0,0 @@
-export interface ConstructorOption {
-    state?: any;
-    mutations?: any;
-    middlewares?: {
-        snapshot: boolean;
-        onInit: Function;
-        onMutation: Function;
-    }[];
-    strict?: boolean;
-    modules?: any;
-}
-
-export class Store<S> {
-    constructor(obj: ConstructorOption);
-    state: S;
-    dispatch(mutationName: any, ...args: any[]): void;
-    watch(pathOrGetter: (string | Function), cb: Function, options: any): void;
-}
-
-export function install(...args: any[]): any;

+ 0 - 12
tsconfig.json

@@ -1,12 +0,0 @@
-{
-    "compilerOptions": {
-        "module": "commonjs",
-        "target": "es5",
-        "noImplicitAny": true,
-        "sourceMap": false,
-        "experimentalDecorators": true
-    },
-    "exclude": [
-        "node_modules"
-    ]
-}

+ 7 - 0
types/README.md

@@ -0,0 +1,7 @@
+This is the TypeScript declaration of Vuex.
+
+## Testing
+
+```sh
+$ tsc -p test/tsconfig.json
+```

+ 95 - 0
types/index.d.ts

@@ -0,0 +1,95 @@
+declare namespace Vuex {
+  class Store<S> {
+    constructor(options: StoreOption<S>);
+
+    state: S;
+
+    dispatch(mutationName: string, ...args: any[]): void;
+    dispatch<P>(mutation: MutationObject<P>): void;
+
+    replaceState(state: S): void;
+
+    watch<T>(getter: Getter<S, T>, cb: (value: T) => void, options?: WatchOption): void;
+
+    hotUpdate(options: {
+      mutations?: MutationTree<S>;
+      modules?: ModuleTree;
+    }): void;
+
+    on(event: string, cb: (...args: any[]) => void): void;
+    once(event: string, cb: (...args: any[]) => void): void;
+    off(event?: string, cb?: (...args: any[]) => void): void;
+    emit(event: string, ...args: any[]): void;
+  }
+
+  function install(Vue: vuejs.VueStatic): void;
+
+  interface StoreOption<S> {
+    state?: S;
+    mutations?: MutationTree<S>;
+    modules?: ModuleTree;
+    plugins?: Plugin<S>[];
+    strict?: boolean;
+  }
+
+  type Getter<S, T> = (state: S) => T;
+  type Action<S> = (store: Store<S>, ...args: any[]) => any;
+  type Mutation<S> = (state: S, ...args: any[]) => void;
+  type Plugin<S> = (store: Store<S>) => void;
+
+  interface MutationTree<S> {
+    [key: string]: Mutation<S>;
+  }
+
+  interface MutationObject<P> {
+    type: string;
+    silent?: boolean;
+    payload?: P;
+  }
+
+  interface Module<S> {
+    state: S;
+    mutations: MutationTree<S>;
+  }
+
+  interface ModuleTree {
+    [key: string]: Module<any>;
+  }
+
+  interface ComponentOption<S> {
+    getters: { [key: string]: Getter<S, any> };
+    actions: { [key: string]: Action<S> };
+  }
+
+  interface WatchOption {
+    deep?: boolean;
+    immidiate?: boolean;
+  }
+
+  function createLogger<S>(option: LoggerOption<S>): Plugin<S>;
+
+  interface LoggerOption<S> {
+    collapsed?: boolean;
+    transformer?: (state: S) => any;
+    mutationTransformer?: (mutation: MutationObject<any>) => any;
+  }
+}
+
+declare namespace vuejs {
+  interface ComponentOption {
+    vuex?: Vuex.ComponentOption<any>;
+    store?: Vuex.Store<any>;
+  }
+
+  interface Vue {
+    $store?: Vuex.Store<any>;
+  }
+}
+
+declare module 'vuex' {
+  export = Vuex
+}
+
+declare module 'vuex/logger' {
+  export default Vuex.createLogger;
+}

+ 200 - 0
types/test/index.ts

@@ -0,0 +1,200 @@
+import * as Vue from 'vue';
+import * as Vuex from 'vuex';
+import createLogger from 'vuex/logger';
+
+Vue.use(Vuex);
+
+interface ISimpleState {
+  count: number;
+}
+
+const INCREMENT = 'INCREMENT';
+const INCREMENT_OBJECT = 'INCREMENT_OBJECT';
+
+function createStore(): Vuex.Store<ISimpleState> {
+  const state: ISimpleState = {
+    count: 0
+  };
+
+  const mutations: Vuex.MutationTree<ISimpleState> = {
+    [INCREMENT] (state: ISimpleState, amount: number) {
+      state.count = state.count + amount;
+    },
+    [INCREMENT_OBJECT] (state: ISimpleState, payload: number) {
+      state.count = state.count + payload;
+    }
+  };
+
+  return new Vuex.Store({
+    state,
+    mutations,
+    strict: true
+  });
+}
+
+namespace TestDispatch {
+  const store = createStore();
+
+  store.dispatch(INCREMENT, 1);
+  store.dispatch({
+    type: INCREMENT_OBJECT,
+    silent: true,
+    payload: 10
+  });
+}
+
+namespace TestWithComponent {
+  const store = createStore();
+
+  const a: vuejs.ComponentOption = {
+    vuex: {
+      getters: {
+        count: (state: ISimpleState) => state.count
+      },
+      actions: {
+        incrementCounter({ dispatch, state }: Vuex.Store<ISimpleState>) {
+          dispatch(INCREMENT, 1);
+        }
+      }
+    }
+  };
+
+  const app = new Vue({
+    el: '#app',
+    components: { a },
+    store
+  });
+
+  const b: number = app.$store.state.count;
+}
+
+namespace TestModules {
+  interface IModuleAState {
+    value: number;
+  }
+
+  interface IModuleBState {
+    value: string;
+  }
+
+  interface IModuleState {
+    a: IModuleAState;
+    b: IModuleBState;
+  }
+
+  const aState: IModuleAState = { value: 1 };
+  const bState: IModuleBState = { value: 'test' };
+
+  const aMutations: Vuex.MutationTree<IModuleAState> = {
+    INCREMENT (state: IModuleAState) {
+      state.value = state.value + 1;
+    }
+  };
+
+  const bMutations: Vuex.MutationTree<IModuleBState> = {
+    APPEND (state: IModuleBState, value: string) {
+      state.value = state.value + value;
+    }
+  };
+
+  const a = { state: aState, mutations: aMutations };
+  const b = { state: bState, mutations: bMutations };
+
+  const store = new Vuex.Store<IModuleState>({
+    modules: { a, b }
+  });
+
+  const valA: number = store.state.a.value;
+  const valB: string = store.state.b.value;
+}
+
+namespace TestPlugin {
+  const a = (store: Vuex.Store<any>) => {};
+
+  const b = (store: Vuex.Store<ISimpleState>) => {};
+
+  new Vuex.Store<ISimpleState>({
+    state: { count: 1 },
+    plugins: [a, b]
+  });
+}
+
+namespace TestReplaceState {
+  const store = createStore();
+
+  store.replaceState({ count: 10 });
+}
+
+namespace TestWatch {
+  const store = createStore();
+
+  store.watch(state => state.count, value => {
+    const a: number = value;
+  }, {
+    deep: true,
+    immidiate: true
+  });
+}
+
+namespace TestHotUpdate {
+  const store = createStore();
+
+  store.hotUpdate({
+    mutations: {
+      INCREMENT (state) {
+        state.count += 10;
+      }
+    }
+  });
+
+  store.hotUpdate({
+    modules: {
+      a: {
+        state: 1,
+        mutations: {
+          INCREMENT (state) {
+            state.value++;
+          }
+        }
+      },
+      b: {
+        state: 'test',
+        mutations: {
+          APPEND (state, value) {
+            state.value += value;
+          }
+        }
+      }
+    }
+  });
+}
+
+namespace TestEvents {
+  const store = createStore();
+
+  const handler = (mutation: Vuex.MutationObject<any>, state: ISimpleState) => {
+    state.count += 1;
+  };
+
+  store.on('mutation', handler);
+  store.once('mutation', handler);
+
+  store.off();
+  store.off('mutation');
+  store.off('mutation', handler);
+
+  store.emit('some-event', 1, 'a', []);
+}
+
+namespace TestLogger {
+  const logger = createLogger<ISimpleState>({
+    collapsed: false,
+    transformer: state => state.count,
+    mutationTransformer: m => m
+  });
+
+  new Vuex.Store<ISimpleState>({
+    state: { count: 1 },
+    plugins: [logger]
+  });
+}

+ 12 - 0
types/test/tsconfig.json

@@ -0,0 +1,12 @@
+{
+  "compilerOptions": {
+    "module": "commonjs",
+    "target": "es5",
+    "noImplicitAny": true
+  },
+  "files": [
+    "index.ts",
+    "../index.d.ts",
+    "../typings/index.d.ts"
+  ]
+}

+ 11 - 0
types/tsconfig.json

@@ -0,0 +1,11 @@
+{
+  "compilerOptions": {
+    "module": "commonjs",
+    "target": "es5",
+    "noImplicitAny": true
+  },
+  "files": [
+    "index.d.ts",
+    "typings/index.d.ts"
+  ]
+}

+ 7 - 0
types/typings.json

@@ -0,0 +1,7 @@
+{
+  "name": "vuex",
+  "main": "index.d.ts",
+  "globalDependencies": {
+    "vue": "registry:dt/vue#1.0.21+20160423143248"
+  }
+}