From 442c88f22ff072cf1e9f49c00cf252865723c916 Mon Sep 17 00:00:00 2001 From: ktsn Date: Sun, 19 Jun 2016 21:56:23 +0900 Subject: [PATCH 1/8] Update the declaration and its dependency for typings --- .gitignore | 1 + index.d.ts | 20 --------- tsconfig.json | 12 ------ types/index.d.ts | 100 ++++++++++++++++++++++++++++++++++++++++++++ types/tsconfig.json | 11 +++++ types/typings.json | 7 ++++ 6 files changed, 119 insertions(+), 32 deletions(-) delete mode 100644 index.d.ts delete mode 100644 tsconfig.json create mode 100644 types/index.d.ts create mode 100644 types/tsconfig.json create mode 100644 types/typings.json diff --git a/.gitignore b/.gitignore index 6f4c325d8..b7063bdcc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ lib docs/_book logger.js examples/**/build.js +types/typings diff --git a/index.d.ts b/index.d.ts deleted file mode 100644 index 1cca1ae80..000000000 --- a/index.d.ts +++ /dev/null @@ -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 { - 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; diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 03a8d3afc..000000000 --- a/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": true, - "sourceMap": false, - "experimentalDecorators": true - }, - "exclude": [ - "node_modules" - ] -} \ No newline at end of file diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 000000000..3b37bc366 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,100 @@ +declare namespace Vuex { + class Store { + constructor(options: StoreOption); + + state: S; + + dispatch(mutationName: string, ...args: any[]): void; + dispatch

(mutation: MutationObject

): void; + + watch(path: string, cb: (value: any) => void, options?: WatchOption): void; + watch(getter: Getter, cb: (value: T) => void, options?: WatchOption): void; + + hotUpdate(options: { + mutations?: MutationTree; + modules?: ModuleTree; + }): void; + } + + function install(Vue: vuejs.VueStatic): void; + + interface StoreOption { + state?: S; + mutations?: MutationTree; + modules?: ModuleTree; + middlewares?: (Middleware | SnapshotMiddleware)[]; + strict?: boolean; + } + + type Getter = (state: S) => T; + type Action = (store: Store, ...args: any[]) => any; + type Mutation = (state: S, ...args: any[]) => void; + + interface MutationTree { + [key: string]: Mutation; + } + + interface MutationObject

{ + type: string; + silent?: boolean; + payload?: P; + } + + interface Module { + state: S; + mutations: MutationTree; + } + + interface ModuleTree { + [key: string]: Module; + } + + interface Middleware { + snapshot?: boolean; + onInit?(state: S, store: Store): void; + onMutation?(mutation: MutationObject, state: S, store: Store): void; + } + + interface SnapshotMiddleware { + snapshot: boolean; + onInit?(state: S, store: Store): void; + onMutation?(mutation: MutationObject, nextState: S, prevState: S, store: Store): void; + } + + interface ComponentOption { + getters: { [key: string]: Getter }; + actions: { [key: string]: Action }; + } + + interface WatchOption { + deep?: boolean; + immidiate?: boolean; + } + + function createLogger(option: LoggerOption): SnapshotMiddleware; + + interface LoggerOption { + collapsed?: boolean; + transformer?: (state: S) => any; + mutationTransformer?: (mutation: MutationObject) => any; + } +} + +declare namespace vuejs { + interface ComponentOption { + vuex?: Vuex.ComponentOption; + store?: Vuex.Store; + } + + interface Vue { + $store?: Vuex.Store; + } +} + +declare module 'vuex' { + export = Vuex +} + +declare module 'vuex/logger' { + export default Vuex.createLogger; +} diff --git a/types/tsconfig.json b/types/tsconfig.json new file mode 100644 index 000000000..9f252feec --- /dev/null +++ b/types/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": true + }, + "files": [ + "index.d.ts", + "typings/index.d.ts" + ] +} diff --git a/types/typings.json b/types/typings.json new file mode 100644 index 000000000..40f058fa7 --- /dev/null +++ b/types/typings.json @@ -0,0 +1,7 @@ +{ + "name": "vuex", + "main": "index.d.ts", + "globalDependencies": { + "vue": "registry:dt/vue#1.0.21+20160423143248" + } +} From f31111988e8b205b8abb3034af7e99f8d6937394 Mon Sep 17 00:00:00 2001 From: ktsn Date: Sun, 19 Jun 2016 21:58:12 +0900 Subject: [PATCH 2/8] Add a test for the declaration --- .gitignore | 1 + types/test/index.ts | 200 +++++++++++++++++++++++++++++++++++++++ types/test/tsconfig.json | 12 +++ 3 files changed, 213 insertions(+) create mode 100644 types/test/index.ts create mode 100644 types/test/tsconfig.json diff --git a/.gitignore b/.gitignore index b7063bdcc..ba771a576 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ docs/_book logger.js examples/**/build.js types/typings +types/test/*.js diff --git a/types/test/index.ts b/types/test/index.ts new file mode 100644 index 000000000..e0abbf2f7 --- /dev/null +++ b/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 { + const state: ISimpleState = { + count: 0 + }; + + const mutations: Vuex.MutationTree = { + [INCREMENT] (state: ISimpleState, amount: number) { + state.count = state.count + amount; + }, + [INCREMENT_OBJECT] (state: ISimpleState, mutation: Vuex.MutationObject) { + state.count = state.count + mutation.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) { + 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 = { + INCREMENT (state: IModuleAState) { + state.value = state.value + 1; + } + }; + + const bMutations: Vuex.MutationTree = { + 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({ + modules: { a, b } + }); + + const valA: number = store.state.a.value; + const valB: string = store.state.b.value; +} + +namespace TestMiddleware { + const a = { + onInit( + state: ISimpleState, + store: Vuex.Store + ) {}, + + onMutation( + mutation: Vuex.MutationObject, + state: ISimpleState, + store: Vuex.Store + ) {} + }; + + const b = { + snapshot: true, + onMutation( + mutation: Vuex.MutationObject, + nextState: ISimpleState, + prevState: ISimpleState, + store: Vuex.Store + ) {} + }; + + new Vuex.Store({ + state: { count: 1 }, + middlewares: [a, b] + }); +} + +namespace TestWatch { + const store = createStore(); + + store.watch('count', value => { + const a: number = value; + }); + + 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 TestLogger { + const logger = createLogger({ + collapsed: false, + transformer: state => state.count, + mutationTransformer: m => m + }); + + new Vuex.Store({ + state: { count: 1 }, + middlewares: [logger] + }); +} diff --git a/types/test/tsconfig.json b/types/test/tsconfig.json new file mode 100644 index 000000000..ee07ade35 --- /dev/null +++ b/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" + ] +} From 2216a0c8ba0c053b294ed60cc0bb1010e66723cf Mon Sep 17 00:00:00 2001 From: ktsn Date: Sun, 19 Jun 2016 21:58:29 +0900 Subject: [PATCH 3/8] Add README for the types directory --- types/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 types/README.md diff --git a/types/README.md b/types/README.md new file mode 100644 index 000000000..2e0d5d6e7 --- /dev/null +++ b/types/README.md @@ -0,0 +1,7 @@ +This is the TypeScript declaration of Vuex. + +## Testing + +```sh +$ tsc -p test/tsconfig.json +``` From 1b75580a23236be82b41d060631bcf48ed6d231b Mon Sep 17 00:00:00 2001 From: ktsn Date: Sun, 19 Jun 2016 22:46:24 +0900 Subject: [PATCH 4/8] Fix test case because of incorrect usage --- types/test/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/test/index.ts b/types/test/index.ts index e0abbf2f7..33308aeb7 100644 --- a/types/test/index.ts +++ b/types/test/index.ts @@ -20,8 +20,8 @@ function createStore(): Vuex.Store { [INCREMENT] (state: ISimpleState, amount: number) { state.count = state.count + amount; }, - [INCREMENT_OBJECT] (state: ISimpleState, mutation: Vuex.MutationObject) { - state.count = state.count + mutation.payload; + [INCREMENT_OBJECT] (state: ISimpleState, payload: number) { + state.count = state.count + payload; } }; From 14981bfd83b2f0c1c89a890d40c0739e8149e859 Mon Sep 17 00:00:00 2001 From: ktsn Date: Fri, 1 Jul 2016 09:20:40 +0900 Subject: [PATCH 5/8] Remove deprecated watch API from types --- types/index.d.ts | 1 - types/test/index.ts | 4 ---- 2 files changed, 5 deletions(-) diff --git a/types/index.d.ts b/types/index.d.ts index 3b37bc366..b4bbbd354 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -7,7 +7,6 @@ declare namespace Vuex { dispatch(mutationName: string, ...args: any[]): void; dispatch

(mutation: MutationObject

): void; - watch(path: string, cb: (value: any) => void, options?: WatchOption): void; watch(getter: Getter, cb: (value: T) => void, options?: WatchOption): void; hotUpdate(options: { diff --git a/types/test/index.ts b/types/test/index.ts index 33308aeb7..efb52836c 100644 --- a/types/test/index.ts +++ b/types/test/index.ts @@ -141,10 +141,6 @@ namespace TestMiddleware { namespace TestWatch { const store = createStore(); - store.watch('count', value => { - const a: number = value; - }); - store.watch(state => state.count, value => { const a: number = value; }, { From 90b4fcb19b1e27de0d2c7cfab8f4278adf62703d Mon Sep 17 00:00:00 2001 From: ktsn Date: Fri, 1 Jul 2016 12:32:52 +0900 Subject: [PATCH 6/8] Update types for 1.0 - middlewares -> plugins - new method: replaceState, on, once, off and emit --- types/index.d.ts | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/types/index.d.ts b/types/index.d.ts index b4bbbd354..a6d73bc85 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -7,12 +7,19 @@ declare namespace Vuex { dispatch(mutationName: string, ...args: any[]): void; dispatch

(mutation: MutationObject

): void; + replaceState(state: S): void; + watch(getter: Getter, cb: (value: T) => void, options?: WatchOption): void; hotUpdate(options: { mutations?: MutationTree; 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; @@ -21,13 +28,14 @@ declare namespace Vuex { state?: S; mutations?: MutationTree; modules?: ModuleTree; - middlewares?: (Middleware | SnapshotMiddleware)[]; + plugins?: Plugin[]; strict?: boolean; } type Getter = (state: S) => T; type Action = (store: Store, ...args: any[]) => any; type Mutation = (state: S, ...args: any[]) => void; + type Plugin = (store: Store) => void; interface MutationTree { [key: string]: Mutation; @@ -48,18 +56,6 @@ declare namespace Vuex { [key: string]: Module; } - interface Middleware { - snapshot?: boolean; - onInit?(state: S, store: Store): void; - onMutation?(mutation: MutationObject, state: S, store: Store): void; - } - - interface SnapshotMiddleware { - snapshot: boolean; - onInit?(state: S, store: Store): void; - onMutation?(mutation: MutationObject, nextState: S, prevState: S, store: Store): void; - } - interface ComponentOption { getters: { [key: string]: Getter }; actions: { [key: string]: Action }; @@ -70,7 +66,7 @@ declare namespace Vuex { immidiate?: boolean; } - function createLogger(option: LoggerOption): SnapshotMiddleware; + function createLogger(option: LoggerOption): Plugin; interface LoggerOption { collapsed?: boolean; From 5cf738953e7af5cd8283e52f3f5e54e2850a5d57 Mon Sep 17 00:00:00 2001 From: ktsn Date: Fri, 1 Jul 2016 12:41:09 +0900 Subject: [PATCH 7/8] Add test cases for plugins, replaceState and events --- types/test/index.ts | 52 ++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/types/test/index.ts b/types/test/index.ts index efb52836c..b974abb5d 100644 --- a/types/test/index.ts +++ b/types/test/index.ts @@ -108,36 +108,23 @@ namespace TestModules { const valB: string = store.state.b.value; } -namespace TestMiddleware { - const a = { - onInit( - state: ISimpleState, - store: Vuex.Store - ) {}, - - onMutation( - mutation: Vuex.MutationObject, - state: ISimpleState, - store: Vuex.Store - ) {} - }; +namespace TestPlugin { + const a = (store: Vuex.Store) => {}; - const b = { - snapshot: true, - onMutation( - mutation: Vuex.MutationObject, - nextState: ISimpleState, - prevState: ISimpleState, - store: Vuex.Store - ) {} - }; + const b = (store: Vuex.Store) => {}; new Vuex.Store({ state: { count: 1 }, - middlewares: [a, b] + plugins: [a, b] }); } +namespace TestReplaceState { + const store = createStore(); + + store.replaceState({ count: 10 }); +} + namespace TestWatch { const store = createStore(); @@ -182,6 +169,23 @@ namespace TestHotUpdate { }); } +namespace TestEvents { + const store = createStore(); + + const handler = (mutation: Vuex.MutationObject, 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({ collapsed: false, @@ -191,6 +195,6 @@ namespace TestLogger { new Vuex.Store({ state: { count: 1 }, - middlewares: [logger] + plugins: [logger] }); } From 2f5f5ff8fc01dad53865030824185ebe9cd0e0a8 Mon Sep 17 00:00:00 2001 From: ktsn Date: Fri, 1 Jul 2016 12:44:21 +0900 Subject: [PATCH 8/8] Fix type of logger plugin --- types/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/index.d.ts b/types/index.d.ts index a6d73bc85..a0f20f9f6 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -66,7 +66,7 @@ declare namespace Vuex { immidiate?: boolean; } - function createLogger(option: LoggerOption): Plugin; + function createLogger(option: LoggerOption): Plugin; interface LoggerOption { collapsed?: boolean;