diff --git a/package.json b/package.json index 303911f2c..d78dbce7b 100644 --- a/package.json +++ b/package.json @@ -17,12 +17,13 @@ "dev:compiler": "TARGET=web-compiler rollup -w -c build/config.js", "build": "node build/build.js", "build:ssr": "npm run build -- vue.common.js,vue-server-renderer", - "test": "npm run lint && flow check && npm run test:cover && npm run test:e2e -- --env phantomjs && npm run test:ssr", + "test": "npm run lint && flow check && npm run test:types && npm run test:cover && npm run test:e2e -- --env phantomjs && npm run test:ssr", "test:unit": "karma start build/karma.unit.config.js", "test:cover": "karma start build/karma.cover.config.js", "test:e2e": "npm run build -- vue.js && node test/e2e/runner.js", "test:ssr": "npm run build:ssr && VUE_ENV=server jasmine JASMINE_CONFIG_PATH=test/ssr/jasmine.json", "test:sauce": "npm run sauce -- 0 && npm run sauce -- 1 && npm run sauce -- 2", + "test:types": "tsc -p ./types/test/tsconfig.json", "lint": "eslint src build test", "flow": "flow check", "sauce": "SAUCE=true karma start build/karma.sauce.config.js", diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 000000000..ec3e0a352 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,2 @@ +import {Vue} from "./vue.d"; +export = Vue; diff --git a/types/options.d.ts b/types/options.d.ts new file mode 100644 index 000000000..2216e4a75 --- /dev/null +++ b/types/options.d.ts @@ -0,0 +1,74 @@ +import { Vue } from "./vue.d"; +import { VNode, VNodeDirective } from "./vnode.d"; + +type Constructor = { + new (...args: any[]): any; +} + +export interface ComponentOptions { + data?: Object | ( (this: Vue) => Object ); + props?: string[] | { [key: string]: PropOptions | Constructor | Constructor[] }; + propsData?: Object; + computed?: { [key: string]: ((this: Vue) => any) | ComputedOptions }; + methods?: { [key: string]: Function }; + watch?: { [key: string]: ({ handler: WatchHandler } & WatchOptions) | WatchHandler | string }; + + el?: Element | String; + template?: string; + render?(createElement: typeof Vue.prototype.$createElement): VNode; + staticRenderFns?: (() => VNode)[]; + + beforeCreate?(): void; + created?(): void; + beforeDestroy?(): void; + destroyed?(): void; + beforeMount?(): void; + mounted?(): void; + beforeUpdate?(): void; + updated?(): void; + + directives?: { [key: string]: DirectiveOptions | DirectiveFunction }; + components?: { [key: string]: ComponentOptions | typeof Vue }; + transitions?: { [key: string]: Object }; + filters?: { [key: string]: Function }; + + parent?: Vue; + mixins?: (ComponentOptions | typeof Vue)[]; + name?: string; + extends?: ComponentOptions | typeof Vue; + delimiters?: [string, string]; +} + +export interface PropOptions { + type?: Constructor | Constructor[] | null; + required?: boolean; + default?: any; + validator?(value: any): boolean; +} + +export interface ComputedOptions { + get?(this: Vue): any; + set?(this: Vue, value: any): void; + cache?: boolean; +} + +export type WatchHandler = (val: T, oldVal: T) => void; + +export interface WatchOptions { + deep?: boolean; + immediate?: boolean; +} + +export type DirectiveFunction = ( + el: HTMLElement, + binding: VNodeDirective, + vnode: VNode, + oldVnode: VNode +) => void; + +export interface DirectiveOptions { + bind?: DirectiveFunction; + update?: DirectiveFunction; + componentUpdated?: DirectiveFunction; + unbind?: DirectiveFunction; +} diff --git a/types/plugin.d.ts b/types/plugin.d.ts new file mode 100644 index 000000000..de8aa0fe4 --- /dev/null +++ b/types/plugin.d.ts @@ -0,0 +1,8 @@ +import { Vue as _Vue } from "./vue.d"; + +export type PluginFunction = (Vue: typeof _Vue, options?: T) => void; + +export interface PluginObject { + install: PluginFunction; + [key: string]: any; +} diff --git a/types/test/options-test.ts b/types/test/options-test.ts new file mode 100644 index 000000000..23af5cde7 --- /dev/null +++ b/types/test/options-test.ts @@ -0,0 +1,136 @@ +import { Vue } from "../vue.d"; +import { ComponentOptions } from "../options.d"; + +interface Component extends Vue { + a: number; +} + +const Options: ComponentOptions = { + data() { + return { + a: 1 + } + }, + props: { + size: Number, + name: { + type: String, + default: 0, + required: true, + validator(value) { + return value > 0; + } + } + }, + propsData: { + msg: "Hello" + }, + computed: { + aDouble(this: Component) { + return this.a * 2; + }, + aPlus: { + get(this: Component) { + return this.a + 1; + }, + set(this: Component, v: number) { + this.a = v - 1; + }, + cache: false + } + }, + methods: { + plus(this: Component) { + this.a++; + } + }, + watch: { + 'a': function(val: number, oldVal: number) { + console.log(`new: ${val}, old: ${oldVal}`); + }, + 'b': 'someMethod', + 'c': { + handler(val: number, oldval: number) {}, + deep: true + } + }, + el: "#app", + template: "
{{ message }}
", + render(createElement) { + return createElement("div", { + attrs: { + id: "foo" + }, + props: { + myProp: "bar" + }, + domProps: { + innerHTML: "baz" + }, + on: { + click: new Function + }, + nativeOn: { + click: new Function + }, + class: { + foo: true, + bar: false + }, + style: { + color: 'red', + fontSize: '14px' + }, + key: 'myKey', + ref: 'myRef' + }, [ + createElement("div", {}, "message"), + "message", + [createElement("div", {}, "message")] + ]); + }, + staticRenderFns: [], + + beforeCreate() {}, + created() {}, + beforeDestroy() {}, + destroyed() {}, + beforeMount() {}, + mounted() {}, + beforeUpdate() {}, + updated() {}, + + directives: { + a: { + bind() {}, + update() {}, + componentMounted() {}, + unbind() {} + }, + b(el, binding, vnode, oldVnode) { + el.textContent; + + binding.name; + binding.value; + binding.oldValue; + binding.expression; + binding.arg; + binding.modifiers["modifier"]; + } + }, + components: { + a: Vue.component(""), + b: {} as ComponentOptions + }, + transitions: {}, + filters: { + double(value: number) { + return value * 2; + } + }, + parent: new Vue, + mixins: [Vue.component(""), ({} as ComponentOptions)], + name: "Component", + extends: {} as ComponentOptions, + delimiters: ["${", "}"] +} diff --git a/types/test/plugin-test.ts b/types/test/plugin-test.ts new file mode 100644 index 000000000..fa4f8313f --- /dev/null +++ b/types/test/plugin-test.ts @@ -0,0 +1,19 @@ +import { Vue } from "../vue.d"; +import { PluginFunction, PluginObject } from "../plugin.d"; + +class Option { + prefix: string; + suffix: string; +} + +const plugin: PluginObject