diff --git a/types/options.d.ts b/types/options.d.ts index 2216e4a7..efa536cb 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -1,10 +1,12 @@ import { Vue } from "./vue.d"; -import { VNode, VNodeDirective } from "./vnode.d"; +import { VNode, VNodeData, VNodeDirective } from "./vnode.d"; type Constructor = { new (...args: any[]): any; } +type $createElement = typeof Vue.prototype.$createElement; + export interface ComponentOptions { data?: Object | ( (this: Vue) => Object ); props?: string[] | { [key: string]: PropOptions | Constructor | Constructor[] }; @@ -15,7 +17,7 @@ export interface ComponentOptions { el?: Element | String; template?: string; - render?(createElement: typeof Vue.prototype.$createElement): VNode; + render?(createElement: $createElement): VNode; staticRenderFns?: (() => VNode)[]; beforeCreate?(): void; @@ -28,7 +30,7 @@ export interface ComponentOptions { updated?(): void; directives?: { [key: string]: DirectiveOptions | DirectiveFunction }; - components?: { [key: string]: ComponentOptions | typeof Vue }; + components?: { [key: string]: ComponentOptions | FunctionalComponentOptions | typeof Vue }; transitions?: { [key: string]: Object }; filters?: { [key: string]: Function }; @@ -39,6 +41,21 @@ export interface ComponentOptions { delimiters?: [string, string]; } +export interface FunctionalComponentOptions { + props?: string[] | { [key: string]: PropOptions | Constructor | Constructor[] }; + functional: boolean; + render(this: never, createElement: $createElement, context: RenderContext): VNode; + name?: string; +} + +export interface RenderContext { + props: any; + children: VNode[]; + slots: any; + data: VNodeData; + parent: Vue; +} + export interface PropOptions { type?: Constructor | Constructor[] | null; required?: boolean; diff --git a/types/test/options-test.ts b/types/test/options-test.ts index 3c489ced..f7e7f35b 100644 --- a/types/test/options-test.ts +++ b/types/test/options-test.ts @@ -1,11 +1,12 @@ import Vue = require("../index.d"); import { ComponentOptions } from "../options.d"; +import { FunctionalComponentOptions } from "../options.d"; interface Component extends Vue { a: number; } -const Options: ComponentOptions = { +Vue.component('component', { data() { return { a: 1 @@ -133,4 +134,17 @@ const Options: ComponentOptions = { name: "Component", extends: {} as ComponentOptions, delimiters: ["${", "}"] -} +} as ComponentOptions); + +Vue.component('functional-component', { + props: ['prop'], + functional: true, + render(createElement, context) { + context.props; + context.children; + context.slots; + context.data; + context.parent; + return createElement("div", {}, context.children); + } +} as FunctionalComponentOptions); diff --git a/types/vue.d.ts b/types/vue.d.ts index da5e55bc..847640a5 100644 --- a/types/vue.d.ts +++ b/types/vue.d.ts @@ -1,5 +1,6 @@ import { ComponentOptions, + FunctionalComponentOptions, WatchOptions, WatchHandler, DirectiveOptions, @@ -59,11 +60,20 @@ export declare class Vue { static set(array: T[], key: number, value: T): T; static delete(object: Object, key: string): void; - static directive(id: string, definition?: DirectiveOptions | DirectiveFunction): DirectiveOptions; + static directive( + id: string, + definition?: DirectiveOptions | DirectiveFunction + ): DirectiveOptions; static filter(id: string, definition?: Function): Function; - static component(id: string, definition?: ComponentOptions | typeof Vue): typeof Vue; + static component( + id: string, + definition?: ComponentOptions | FunctionalComponentOptions | typeof Vue + ): typeof Vue; static use(plugin: PluginObject | PluginFunction, options?: T): void; static mixin(mixin: typeof Vue | ComponentOptions): void; - static compile(template: string): { render: Function, staticRenderFns: Function }; + static compile(template: string): { + render(createElement: typeof Vue.prototype.$createElement): VNode; + staticRenderFns: (() => VNode)[]; + }; }