Skip to content

Commit ef69459

Browse files
Kaorun343yyx990803
authored andcommitted
Fix $createElement and Vue.extend (#3818)
* Fix $createElement and extend * Add AsyncComponent
1 parent 47ee6ab commit ef69459

File tree

6 files changed

+49
-10
lines changed

6 files changed

+49
-10
lines changed

types/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import * as VNode from "./vnode";
66
// `Vue` in `export = Vue` must be a namespace
77
// All available types are exported via this namespace
88
declare namespace Vue {
9+
export type Component = Options.Component;
10+
export type AsyncComponent = Options.AsyncComponent;
911
export type ComponentOptions<V extends Vue> = Options.ComponentOptions<V>;
1012
export type FunctionalComponentOptions = Options.FunctionalComponentOptions;
1113
export type RenderContext = Options.RenderContext;

types/options.d.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ type Constructor = {
77

88
type $createElement = typeof Vue.prototype.$createElement;
99

10+
export type Component = typeof Vue | ComponentOptions<Vue> | FunctionalComponentOptions;
11+
export type AsyncComponent = (
12+
resolve: (component: Component) => void,
13+
reject: (reason?: any) => void
14+
) => Promise<Component> | Component | void;
15+
1016
export interface ComponentOptions<V extends Vue> {
1117
data?: Object | ((this: V) => Object);
1218
props?: string[] | { [key: string]: PropOptions | Constructor | Constructor[] };
@@ -30,7 +36,7 @@ export interface ComponentOptions<V extends Vue> {
3036
updated?(this: V): void;
3137

3238
directives?: { [key: string]: DirectiveOptions | DirectiveFunction };
33-
components?: { [key: string]: ComponentOptions<Vue> | FunctionalComponentOptions | typeof Vue };
39+
components?: { [key: string]: Component | AsyncComponent };
3440
transitions?: { [key: string]: Object };
3541
filters?: { [key: string]: Function };
3642

types/test/options-test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,24 @@ Vue.component('component', {
8989
ref: 'myRef'
9090
}, [
9191
createElement("div", {}, "message"),
92+
createElement(Vue.component("component")),
93+
createElement({} as ComponentOptions<Vue>),
94+
createElement({ functional: true }),
95+
96+
createElement(() => Vue.component("component")),
97+
createElement(() => ( {} as ComponentOptions<Vue> )),
98+
createElement(() => {
99+
return new Promise((resolve) => {
100+
resolve({} as ComponentOptions<Vue>);
101+
})
102+
}),
103+
createElement((resolve, reject) => {
104+
resolve({} as ComponentOptions<Vue>);
105+
reject();
106+
}),
107+
92108
"message",
109+
93110
[createElement("div", {}, "message")]
94111
]);
95112
},
@@ -154,3 +171,12 @@ Vue.component('functional-component', {
154171
return createElement("div", {}, context.children);
155172
}
156173
} as FunctionalComponentOptions);
174+
175+
Vue.component("async-component", (resolve, reject) => {
176+
setTimeout(() => {
177+
resolve(Vue.component("component"));
178+
}, 0);
179+
return new Promise((resolve) => {
180+
resolve({ functional: true } as FunctionalComponentOptions);
181+
})
182+
});

types/test/tsconfig.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
{
22
"compilerOptions": {
33
"target": "es5",
4+
"lib": [
5+
"es5",
6+
"dom",
7+
"es2015.promise",
8+
"es2015.core"
9+
],
410
"module": "commonjs",
511
"noImplicitAny": true,
612
"strictNullChecks": true,

types/test/vue-test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class Test extends Vue {
4545
this.$nextTick(function() {
4646
this.$nextTick;
4747
});
48-
this.$createElement("div", {}, "message", "");
48+
this.$createElement("div", {}, "message");
4949
}
5050

5151
static testConfig() {
@@ -77,6 +77,7 @@ class Test extends Vue {
7777
this.directive("", {bind() {}});
7878
this.filter("", (value: number) => value);
7979
this.component("", { data: () => ({}) });
80+
this.component("", { functional: true });
8081
this.use;
8182
this.mixin(Test);
8283
this.compile("<div>{{ message }}</div>");

types/vue.d.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import {
2+
Component,
3+
AsyncComponent,
24
ComponentOptions,
35
FunctionalComponentOptions,
46
WatchOptions,
@@ -39,10 +41,9 @@ export declare class Vue {
3941
$emit(event: string, ...args: any[]): this;
4042
$nextTick(callback?: (this: this) => void): void;
4143
$createElement(
42-
tag?: string | Vue,
44+
tag?: string | Component | AsyncComponent,
4345
data?: VNodeData,
44-
children?: VNodeChildren,
45-
namespace?: string
46+
children?: VNodeChildren
4647
): VNode;
4748

4849

@@ -54,7 +55,7 @@ export declare class Vue {
5455
keyCodes: { [key: string]: number };
5556
}
5657

57-
static extend(options: ComponentOptions<Vue>): typeof Vue;
58+
static extend(options: ComponentOptions<Vue> | FunctionalComponentOptions): typeof Vue;
5859
static nextTick(callback: () => void, context?: any[]): void;
5960
static set<T>(object: Object, key: string, value: T): T;
6061
static set<T>(array: T[], key: number, value: T): T;
@@ -65,10 +66,7 @@ export declare class Vue {
6566
definition?: DirectiveOptions | DirectiveFunction
6667
): DirectiveOptions;
6768
static filter(id: string, definition?: Function): Function;
68-
static component(
69-
id: string,
70-
definition?: ComponentOptions<Vue> | FunctionalComponentOptions | typeof Vue
71-
): typeof Vue;
69+
static component(id: string, definition?: Component | AsyncComponent): typeof Vue;
7270

7371
static use<T>(plugin: PluginObject<T> | PluginFunction<T>, options?: T): void;
7472
static mixin(mixin: typeof Vue | ComponentOptions<Vue>): void;

0 commit comments

Comments
 (0)