Skip to content

Commit c8f3d6b

Browse files
Kaorun343yyx990803
Kaorun343
authored andcommitted
add types for Vue 1.x (#4731)
* add types for Vue 1.x * add missing types and remove unnecessary option
1 parent f589753 commit c8f3d6b

12 files changed

+577
-1
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"bugs": "https://github.com/vuejs/vue/issues",
2525
"homepage": "http://vuejs.org",
2626
"scripts": {
27-
"test": "npm run lint && npm run cover && npm run build && npm run e2e",
27+
"test": "npm run lint && npm run cover && npm run build && npm run e2e && npm run types",
2828
"build": "node build/build.js",
2929
"install-hook": "ln -s ../../build/git-hooks/pre-commit .git/hooks/pre-commit",
3030
"dev": "webpack --watch --config build/webpack.dev.config.js & npm run serve-test",
@@ -34,6 +34,7 @@
3434
"e2e": "casperjs test --concise ./test/e2e",
3535
"unit": "karma start build/karma.unit.config.js",
3636
"cover": "karma start build/karma.cover.config.js",
37+
"types": "tsc -p ./types/test/tsconfig.json",
3738
"sauce": "karma start build/karma.sauce.config.js",
3839
"sauce-all": "npm run sauce && npm run sauce -- 1 && npm run sauce -- 2",
3940
"release": "bash build/release.sh",
@@ -74,6 +75,7 @@
7475
"rollup": "^0.34.13",
7576
"rollup-plugin-babel": "^1.0.0",
7677
"rollup-plugin-replace": "^1.1.0",
78+
"typescript": "^2.1.5",
7779
"uglify-js": "^2.4.24",
7880
"webpack": "^1.12.2",
7981
"webpack-dev-server": "^1.12.1"

types/index.d.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import * as V from './vue';
2+
import * as Options from './options';
3+
import * as Plugin from './plugin';
4+
5+
declare global {
6+
interface Array<T> {
7+
$remove(item: T): Array<T>;
8+
$set(index: any, val: T): T;
9+
}
10+
11+
// For the projects/tools that depend on this namespace
12+
namespace vuejs {
13+
export type PropOption = Options.PropOptions;
14+
export type ComputedOption = Options.ComputedOptions<any>;
15+
export type WatchOption = Options.WatchOptions;
16+
export type DirectiveOption = Options.DirectiveOptions<Vue>;
17+
export type Directive = Options.DirectiveInstance<Vue>;
18+
export type TransitionOpsion = Options.TransitionOptions;
19+
export type ComponentOption = Options.ComponentOptions<any>;
20+
export type FilterOption = Options.FilterOptions;
21+
export type Vue = V.Vue;
22+
export type VueStatic = typeof V.Vue;
23+
export type VueConfig = typeof V.Vue.config;
24+
}
25+
}
26+
27+
// `Vue` in `export = Vue` must be a namespace
28+
// All available types are exported via this namespace
29+
declare namespace Vue {
30+
31+
export type Component = Options.Component;
32+
export type AsyncComponent = Options.AsyncComponent;
33+
export type ComponentOptions<V extends Vue> = Options.ComponentOptions<V>;
34+
export type PropOptions = Options.PropOptions;
35+
export type ComputedOptions<V extends Vue> = Options.ComputedOptions<V>;
36+
export type WatchHandler<V extends Vue> = Options.WatchHandler<V>;
37+
export type WatchOptions = Options.WatchOptions;
38+
export type DirectiveInstance<V extends Vue> = Options.DirectiveInstance<V>;
39+
export type DirectiveFunction<V extends Vue> = Options.DirectiveFunction<V>;
40+
export type DirectiveOptions<V extends Vue> = Options.DirectiveOptions<V>;
41+
export type FilterOptions = Options.FilterOptions;
42+
export type TransitionOpsions = Options.TransitionOptions;
43+
44+
export type PluginFunction<T> = Plugin.PluginFunction<T>;
45+
export type PluginObject<T> = Plugin.PluginObject<T>;
46+
}
47+
48+
// TS cannot merge imported class with namespace, declare a subclass to bypass
49+
declare class Vue extends V.Vue { }
50+
51+
export = Vue;

types/options.d.ts

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { Vue } from './vue';
2+
3+
type Constructor = {
4+
new (...args: any[]): any;
5+
};
6+
7+
type Dictionary<T> = {
8+
[key: string]: T;
9+
};
10+
11+
export type Component = ComponentOptions<Vue> | typeof Vue;
12+
export type AsyncComponent = (
13+
resolve: (component: Component) => void,
14+
reject: (reason?: any) => void
15+
) => Promise<Component> | Component | void;
16+
17+
export interface ComponentOptions<V extends Vue> {
18+
data?: Dictionary<any> | ((this: V) => Dictionary<any>);
19+
props?: string[] | Dictionary<PropOptions | Constructor | Constructor[]>;
20+
propsData?: Dictionary<any>;
21+
computed?: Dictionary<((this: V) => any) | ComputedOptions<V>>;
22+
methods?: Dictionary<(this: V, ...args: any[]) => any>;
23+
watch?: Dictionary<({ handler: WatchHandler<V> } & WatchOptions) | WatchHandler<V> | string>;
24+
25+
el?: string | HTMLElement | (() => HTMLElement);
26+
template?: string;
27+
replace?: boolean;
28+
29+
init?(this: V): void;
30+
created?(this: V): void;
31+
beforeCompile?(this: V): void;
32+
compiled?(this: V): void;
33+
activate?(this: V, done: () => void): void;
34+
ready?(this: V): void;
35+
attached?(this: V): void;
36+
detached?(this: V): void;
37+
beforeDestroy?(this: V): void;
38+
destroyed?(this: V): void;
39+
40+
directives?: Dictionary<DirectiveOptions<V> | DirectiveFunction<V>>;
41+
elementDirectives?: Dictionary<DirectiveOptions<V> | Function>;
42+
filters?: Dictionary<Function | FilterOptions>;
43+
components?: Dictionary<Component | AsyncComponent>;
44+
transitions?: Dictionary<TransitionOptions>;
45+
partials?: Dictionary<string>;
46+
47+
parent?: Vue;
48+
events?: Dictionary<((...args: any[]) => (boolean | void)) | string>;
49+
mixins?: (ComponentOptions<Vue> | typeof Vue)[];
50+
name?: string;
51+
}
52+
53+
export interface PropOptions {
54+
type?: Constructor | Constructor[] | null;
55+
required?: boolean;
56+
default?: any;
57+
twoWay?: boolean;
58+
validator?(value: any): boolean;
59+
coerce?(value: any): any;
60+
}
61+
62+
export interface ComputedOptions<V extends Vue> {
63+
get?(this: V): any;
64+
set(this: V, value: any): void;
65+
}
66+
67+
export type WatchHandler<V> = (this: V, val: any, oldVal: any) => void;
68+
69+
export interface WatchOptions {
70+
deep?: boolean;
71+
immediate?: boolean;
72+
}
73+
74+
export interface DirectiveInstance<V extends Vue> {
75+
el: HTMLElement;
76+
vm: V;
77+
expression: string;
78+
arg?: string;
79+
name: string;
80+
modifiers: Dictionary<boolean>;
81+
descriptor: any;
82+
params?: Dictionary<any>;
83+
}
84+
85+
export type DirectiveFunction<V extends Vue> = (this: DirectiveInstance<V>, newVal: any, oldVal: any) => void;
86+
87+
export interface DirectiveOptions<V extends Vue> {
88+
bind?(this: DirectiveInstance<V>): void;
89+
update?(this: DirectiveInstance<V>, newVal: any, oldVal: any): void;
90+
unbind?(this: DirectiveInstance<V>): void;
91+
params?: string[];
92+
deep?: boolean;
93+
twoWay?: boolean;
94+
acceptStatement?: boolean;
95+
terminal?: boolean;
96+
priority?: number;
97+
}
98+
99+
export interface FilterOptions {
100+
read?: Function;
101+
write?: Function;
102+
}
103+
104+
export interface TransitionOptions {
105+
css?: boolean;
106+
animation?: string;
107+
enterClass?: string;
108+
leaveClass?: string;
109+
beforeEnter?(el: HTMLElement): void;
110+
enter?(el: HTMLElement, done: () => void): void;
111+
afterEnter?(el: HTMLElement): void;
112+
enterCancelled?(el: HTMLElement): void;
113+
beforeLeave?(el: HTMLElement): void;
114+
leave?(el: HTMLElement, done: () => void): void;
115+
afterLeave?(el: HTMLElement): void;
116+
leaveCancelled?(el: HTMLElement): void;
117+
stagger?(index: number): number;
118+
enterStagger?(index: number): number;
119+
leaveStagger?(index: number): number;
120+
}

types/plugin.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Vue as _Vue } from './vue';
2+
3+
export type PluginFunction<T> = (Vue: typeof _Vue, options?: T) => void;
4+
5+
export interface PluginObject<T> {
6+
install: PluginFunction<T>;
7+
[key: string]: any;
8+
}
9+
10+
export type Plugin<T> = PluginFunction<T> | PluginObject<T>;

types/test/augmentation-test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import Vue = require("../index");
2+
3+
declare module "../vue" {
4+
// add instance property and method
5+
interface Vue {
6+
$instanceProperty: string;
7+
$instanceMethod(): void;
8+
}
9+
10+
// add static property and method
11+
namespace Vue {
12+
const staticProperty: string;
13+
function staticMethod(): void;
14+
}
15+
}
16+
17+
// augment ComponentOptions
18+
declare module "../options" {
19+
interface ComponentOptions<V extends Vue> {
20+
foo?: string;
21+
}
22+
}
23+
24+
const vm = new Vue({
25+
data: {
26+
a: true
27+
},
28+
foo: "foo"
29+
});
30+
31+
vm.$instanceProperty;
32+
vm.$instanceMethod();
33+
34+
Vue.staticProperty;
35+
Vue.staticMethod();

types/test/global-test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
declare var Vue: vuejs.VueStatic;
2+
3+
var app = new Vue({
4+
data: {
5+
message: ""
6+
}
7+
});
8+
9+
app.$mount("#app");
10+
11+
class Application extends Vue {}
12+
13+
Vue.component("component", {
14+
ready () {
15+
this.a
16+
}
17+
} as vuejs.ComponentOption)

types/test/options-test.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import Vue = require("../index");
2+
import { ComponentOptions } from "../index";
3+
4+
interface Component extends Vue {
5+
a: number;
6+
}
7+
8+
Vue.component('component', {
9+
data() {
10+
this.$mount
11+
this.a
12+
return {
13+
a: 1
14+
}
15+
},
16+
props: {
17+
size: Number,
18+
name: {
19+
type: String,
20+
default: 0,
21+
required: true,
22+
validator(value) {
23+
return value > 0;
24+
}
25+
}
26+
},
27+
propsData: {
28+
msg: "Hello"
29+
},
30+
computed: {
31+
aDouble(this: Component) {
32+
return this.a * 2;
33+
},
34+
aPlus: {
35+
get(this: Component) {
36+
return this.a + 1;
37+
},
38+
set(this: Component, v: number) {
39+
this.a = v - 1;
40+
},
41+
cache: false
42+
}
43+
},
44+
methods: {
45+
plus() {
46+
this.a++;
47+
}
48+
},
49+
watch: {
50+
'a': function(val: number, oldVal: number) {
51+
console.log(`new: ${val}, old: ${oldVal}`);
52+
},
53+
'b': 'someMethod',
54+
'c': {
55+
handler(val, oldVal) {
56+
this.a = val
57+
},
58+
deep: true
59+
}
60+
},
61+
el: "#app",
62+
template: "<div>{{ message }}</div>",
63+
64+
beforeCreate() {
65+
this.a = 1;
66+
},
67+
created() {},
68+
beforeDestroy() {},
69+
destroyed() {},
70+
beforeMount() {},
71+
mounted() {},
72+
beforeUpdate() {},
73+
updated() {},
74+
activated() {},
75+
deactivated() {},
76+
77+
directives: {
78+
a: {
79+
bind() {},
80+
inserted() {},
81+
update() {},
82+
componentMounted() {},
83+
unbind() {}
84+
},
85+
b(val, newVal) {
86+
this.el.textContent;
87+
88+
this.name;
89+
this.expression;
90+
this.arg;
91+
this.modifiers["modifier"];
92+
}
93+
},
94+
components: {
95+
a: Vue.component(""),
96+
b: {} as ComponentOptions<Vue>
97+
},
98+
transitions: {},
99+
filters: {
100+
double(value: number) {
101+
return value * 2;
102+
}
103+
},
104+
parent: new Vue,
105+
mixins: [Vue.component(""), ({} as ComponentOptions<Vue>)],
106+
name: "Component",
107+
extends: {} as ComponentOptions<Vue>,
108+
delimiters: ["${", "}"]
109+
} as ComponentOptions<Component>);
110+
111+
Vue.component("async-component", (resolve, reject) => {
112+
setTimeout(() => {
113+
resolve(Vue.component("component"));
114+
}, 0);
115+
return new Promise((resolve) => {
116+
resolve({ } as ComponentOptions<Vue>);
117+
})
118+
});

0 commit comments

Comments
 (0)