Skip to content

Instantly share code, notes, and snippets.

@wonderful-panda
Created August 7, 2017 04:24
Show Gist options
  • Select an option

  • Save wonderful-panda/49698b48ea41c26753b5e1abc9fb6ca8 to your computer and use it in GitHub Desktop.

Select an option

Save wonderful-panda/49698b48ea41c26753b5e1abc9fb6ca8 to your computer and use it in GitHub Desktop.
Vue component factory which supports type-safe JSX.
import Vue from "vue";
declare type Class<T> = new (...args: any[]) => T;
declare type EventHandlers<E> = {
[K in keyof E]?: (payload: E[K]) => void;
}
declare type ComponentOptions<Props> = Vue.ComponentOptions<Vue> & {
props: PropsDefinition<keyof Props>
};
declare type PropType = Class<any> | Class<any>[] | null;
declare type PropsDefinition<PropKeys extends string> = {
[K in PropKeys]: Vue.PropOptions | PropType;
};
declare interface ElementEvents {
click: Event;
dblclick: Event;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
// ... and so on
}
declare interface ElementEventsNativeOn {
nativeOnClick: Event;
nativeOnDblclick: Event;
nativeOnKeydown: KeyboardEvent;
nativeOnKeyup: KeyboardEvent;
nativeOnKeypress: KeyboardEvent;
// ... and so on
}
declare type TsxComponentAttrs<Props, Events> = (
Props &
Vue.VNodeData &
EventHandlers<Events> &
EventHandlers<ElementEventsNativeOn>
) | (
{ props: Partial<Props> } &
Partial<Props> &
Vue.VNodeData &
EventHandlers<Events> &
EventHandlers<ElementEventsNativeOn>
);
declare type TsxComponent<V extends Vue, Props, Events> = Class<V & {
_tsxattr: TsxComponentAttrs<Props, Events>
}>;
export function convert<V extends Vue>(component: Class<V>): TsxComponent<V, {}, {}> {
return component as any;
}
export function of<Props, Events = {}>(): { convert: <V extends Vue>(component: Class<V>) => TsxComponent<V, Props, Events> } {
return { convert: ((c: Vue) => c) as any };
}
export function createComponent<Props = {}, Events = {}>(opts: ComponentOptions<Props> | Vue.FunctionalComponentOptions): TsxComponent<Vue, Props, Events> {
return Vue.extend(opts) as any;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment