Bladeren bron

Fix $createElement and Vue.extend (#3818)

* Fix $createElement and extend

* Add AsyncComponent
Kaorun343 9 jaren geleden
bovenliggende
commit
ef6945932f
6 gewijzigde bestanden met toevoegingen van 49 en 10 verwijderingen
  1. 2 0
      types/index.d.ts
  2. 7 1
      types/options.d.ts
  3. 26 0
      types/test/options-test.ts
  4. 6 0
      types/test/tsconfig.json
  5. 2 1
      types/test/vue-test.ts
  6. 6 8
      types/vue.d.ts

+ 2 - 0
types/index.d.ts

@@ -6,6 +6,8 @@ import * as VNode from "./vnode";
 // `Vue` in `export = Vue` must be a namespace
 // All available types are exported via this namespace
 declare namespace Vue {
+  export type Component = Options.Component;
+  export type AsyncComponent = Options.AsyncComponent;
   export type ComponentOptions<V extends Vue> = Options.ComponentOptions<V>;
   export type FunctionalComponentOptions = Options.FunctionalComponentOptions;
   export type RenderContext = Options.RenderContext;

+ 7 - 1
types/options.d.ts

@@ -7,6 +7,12 @@ type Constructor = {
 
 type $createElement = typeof Vue.prototype.$createElement;
 
+export type Component = typeof Vue | ComponentOptions<Vue> | FunctionalComponentOptions;
+export type AsyncComponent = (
+  resolve: (component: Component) => void,
+  reject: (reason?: any) => void
+) => Promise<Component> | Component | void;
+
 export interface ComponentOptions<V extends Vue> {
   data?: Object | ((this: V) => Object);
   props?: string[] | { [key: string]: PropOptions | Constructor | Constructor[] };
@@ -30,7 +36,7 @@ export interface ComponentOptions<V extends Vue> {
   updated?(this: V): void;
 
   directives?: { [key: string]: DirectiveOptions | DirectiveFunction };
-  components?: { [key: string]: ComponentOptions<Vue> | FunctionalComponentOptions | typeof Vue };
+  components?: { [key: string]: Component | AsyncComponent };
   transitions?: { [key: string]: Object };
   filters?: { [key: string]: Function };
 

+ 26 - 0
types/test/options-test.ts

@@ -89,7 +89,24 @@ Vue.component('component', {
       ref: 'myRef'
     }, [
       createElement("div", {}, "message"),
+      createElement(Vue.component("component")),
+      createElement({} as ComponentOptions<Vue>),
+      createElement({ functional: true }),
+
+      createElement(() => Vue.component("component")),
+      createElement(() => ( {} as ComponentOptions<Vue> )),
+      createElement(() => {
+        return new Promise((resolve) => {
+          resolve({} as ComponentOptions<Vue>);
+        })
+      }),
+      createElement((resolve, reject) => {
+        resolve({} as ComponentOptions<Vue>);
+        reject();
+      }),
+
       "message",
+
       [createElement("div", {}, "message")]
     ]);
   },
@@ -154,3 +171,12 @@ Vue.component('functional-component', {
     return createElement("div", {}, context.children);
   }
 } as FunctionalComponentOptions);
+
+Vue.component("async-component", (resolve, reject) => {
+  setTimeout(() => {
+    resolve(Vue.component("component"));
+  }, 0);
+  return new Promise((resolve) => {
+    resolve({ functional: true } as FunctionalComponentOptions);
+  })
+});

+ 6 - 0
types/test/tsconfig.json

@@ -1,6 +1,12 @@
 {
   "compilerOptions": {
     "target": "es5",
+    "lib": [
+      "es5",
+      "dom",
+      "es2015.promise",
+      "es2015.core"
+    ],
     "module": "commonjs",
     "noImplicitAny": true,
     "strictNullChecks": true,

+ 2 - 1
types/test/vue-test.ts

@@ -45,7 +45,7 @@ class Test extends Vue {
     this.$nextTick(function() {
       this.$nextTick;
     });
-    this.$createElement("div", {}, "message", "");
+    this.$createElement("div", {}, "message");
   }
 
   static testConfig() {
@@ -77,6 +77,7 @@ class Test extends Vue {
     this.directive("", {bind() {}});
     this.filter("", (value: number) => value);
     this.component("", { data: () => ({}) });
+    this.component("", { functional: true });
     this.use;
     this.mixin(Test);
     this.compile("<div>{{ message }}</div>");

+ 6 - 8
types/vue.d.ts

@@ -1,4 +1,6 @@
 import {
+  Component,
+  AsyncComponent,
   ComponentOptions,
   FunctionalComponentOptions,
   WatchOptions,
@@ -39,10 +41,9 @@ export declare class Vue {
   $emit(event: string, ...args: any[]): this;
   $nextTick(callback?: (this: this) => void): void;
   $createElement(
-    tag?: string | Vue,
+    tag?: string | Component | AsyncComponent,
     data?: VNodeData,
-    children?: VNodeChildren,
-    namespace?: string
+    children?: VNodeChildren
   ): VNode;
 
 
@@ -54,7 +55,7 @@ export declare class Vue {
     keyCodes: { [key: string]: number };
   }
 
-  static extend(options: ComponentOptions<Vue>): typeof Vue;
+  static extend(options: ComponentOptions<Vue> | FunctionalComponentOptions): typeof Vue;
   static nextTick(callback: () => void, context?: any[]): void;
   static set<T>(object: Object, key: string, value: T): T;
   static set<T>(array: T[], key: number, value: T): T;
@@ -65,10 +66,7 @@ export declare class Vue {
     definition?: DirectiveOptions | DirectiveFunction
   ): DirectiveOptions;
   static filter(id: string, definition?: Function): Function;
-  static component(
-    id: string,
-    definition?: ComponentOptions<Vue> | FunctionalComponentOptions | typeof Vue
-  ): typeof Vue;
+  static component(id: string, definition?: Component | AsyncComponent): typeof Vue;
 
   static use<T>(plugin: PluginObject<T> | PluginFunction<T>, options?: T): void;
   static mixin(mixin: typeof Vue | ComponentOptions<Vue>): void;