You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
5.8 KiB
182 lines
5.8 KiB
import { Vue, CreateElement, CombinedVueInstance } from "./vue";
|
|
import { VNode, VNodeData, VNodeDirective } from "./vnode";
|
|
|
|
type Constructor = {
|
|
new (...args: any[]): any;
|
|
}
|
|
|
|
// we don't support infer props in async component
|
|
// N.B. ComponentOptions<V> is contravariant, the default generic should be bottom type
|
|
export type Component<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> =
|
|
| typeof Vue
|
|
| FunctionalComponentOptions<Props>
|
|
| ComponentOptions<never, Data, Methods, Computed, Props>
|
|
|
|
interface EsModuleComponent {
|
|
default: Component
|
|
}
|
|
|
|
export type AsyncComponent<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> = (
|
|
resolve: (component: Component<Data, Methods, Computed, Props>) => void,
|
|
reject: (reason?: any) => void
|
|
) => Promise<Component | EsModuleComponent> | void;
|
|
|
|
/**
|
|
* When the `Computed` type parameter on `ComponentOptions` is inferred,
|
|
* it should have a property with the return type of every get-accessor.
|
|
* Since there isn't a way to query for the return type of a function, we allow TypeScript
|
|
* to infer from the shape of `Accessors<Computed>` and work backwards.
|
|
*/
|
|
export type Accessors<T> = {
|
|
[K in keyof T]: (() => T[K]) | ComputedOptions<T[K]>
|
|
}
|
|
|
|
type DataDef<Data, Props, V> = Data | ((this: Readonly<Props> & V) => Data)
|
|
/**
|
|
* This type should be used when an array of strings is used for a component's `props` value.
|
|
*/
|
|
export type ThisTypedComponentOptionsWithArrayProps<V extends Vue, Data, Methods, Computed, PropNames extends string> =
|
|
object &
|
|
ComponentOptions<V, DataDef<Data, Record<PropNames, any>, V>, Methods, Computed, PropNames[], Record<PropNames, any>> &
|
|
ThisType<CombinedVueInstance<V, Data, Methods, Computed, Readonly<Record<PropNames, any>>>>;
|
|
|
|
/**
|
|
* This type should be used when an object mapped to `PropOptions` is used for a component's `props` value.
|
|
*/
|
|
export type ThisTypedComponentOptionsWithRecordProps<V extends Vue, Data, Methods, Computed, Props> =
|
|
object &
|
|
ComponentOptions<V, DataDef<Data, Props, V>, Methods, Computed, RecordPropsDefinition<Props>, Props> &
|
|
ThisType<CombinedVueInstance<V, Data, Methods, Computed, Readonly<Props>>>;
|
|
|
|
type DefaultData<V> = object | ((this: V) => object);
|
|
type DefaultProps = Record<string, any>;
|
|
type DefaultMethods<V> = { [key: string]: (this: V, ...args: any[]) => any };
|
|
type DefaultComputed = { [key: string]: any };
|
|
export interface ComponentOptions<
|
|
V extends Vue,
|
|
Data=DefaultData<V>,
|
|
Methods=DefaultMethods<V>,
|
|
Computed=DefaultComputed,
|
|
PropsDef=PropsDefinition<DefaultProps>,
|
|
Props=DefaultProps> {
|
|
data?: Data;
|
|
props?: PropsDef;
|
|
propsData?: object;
|
|
computed?: Accessors<Computed>;
|
|
methods?: Methods;
|
|
watch?: Record<string, WatchOptionsWithHandler<any> | WatchHandler<any> | string>;
|
|
|
|
el?: Element | string;
|
|
template?: string;
|
|
// hack is for funcitonal component type inference, should not used in user code
|
|
render?(createElement: CreateElement, hack: RenderContext<Props>): VNode;
|
|
renderError?: (h: () => VNode, err: Error) => VNode;
|
|
staticRenderFns?: ((createElement: CreateElement) => VNode)[];
|
|
|
|
beforeCreate?(this: V): void;
|
|
created?(): void;
|
|
beforeDestroy?(): void;
|
|
destroyed?(): void;
|
|
beforeMount?(): void;
|
|
mounted?(): void;
|
|
beforeUpdate?(): void;
|
|
updated?(): void;
|
|
activated?(): void;
|
|
deactivated?(): void;
|
|
errorCaptured?(err: Error, vm: Vue, info: string): boolean | void;
|
|
|
|
directives?: { [key: string]: DirectiveFunction | DirectiveOptions };
|
|
components?: { [key: string]: Component<any, any, any, any> | AsyncComponent<any, any, any, any> };
|
|
transitions?: { [key: string]: object };
|
|
filters?: { [key: string]: Function };
|
|
|
|
provide?: object | (() => object);
|
|
inject?: InjectOptions;
|
|
|
|
model?: {
|
|
prop?: string;
|
|
event?: string;
|
|
};
|
|
|
|
parent?: Vue;
|
|
mixins?: (ComponentOptions<Vue> | typeof Vue)[];
|
|
name?: string;
|
|
// TODO: support properly inferred 'extends'
|
|
extends?: ComponentOptions<Vue> | typeof Vue;
|
|
delimiters?: [string, string];
|
|
comments?: boolean;
|
|
inheritAttrs?: boolean;
|
|
}
|
|
|
|
export interface FunctionalComponentOptions<Props = DefaultProps, PropDefs = PropsDefinition<Props>> {
|
|
name?: string;
|
|
props?: PropDefs;
|
|
inject?: InjectOptions;
|
|
functional: boolean;
|
|
render?(this: undefined, createElement: CreateElement, context: RenderContext<Props>): VNode;
|
|
}
|
|
|
|
export interface RenderContext<Props=DefaultProps> {
|
|
props: Props;
|
|
children: VNode[];
|
|
slots(): any;
|
|
data: VNodeData;
|
|
parent: Vue;
|
|
listeners: { [key: string]: Function | Function[] };
|
|
injections: any
|
|
}
|
|
|
|
export type Prop<T> = { (): T } | { new (...args: any[]): T & object }
|
|
|
|
export type PropValidator<T> = PropOptions<T> | Prop<T> | Prop<T>[];
|
|
|
|
export interface PropOptions<T=any> {
|
|
type?: Prop<T> | Prop<T>[];
|
|
required?: boolean;
|
|
default?: T | null | undefined | (() => object);
|
|
validator?(value: T): boolean;
|
|
}
|
|
|
|
export type RecordPropsDefinition<T> = {
|
|
[K in keyof T]: PropValidator<T[K]>
|
|
}
|
|
export type ArrayPropsDefinition<T> = (keyof T)[];
|
|
export type PropsDefinition<T> = ArrayPropsDefinition<T> | RecordPropsDefinition<T>;
|
|
|
|
export interface ComputedOptions<T> {
|
|
get?(): T;
|
|
set?(value: T): void;
|
|
cache?: boolean;
|
|
}
|
|
|
|
export type WatchHandler<T> = (val: T, oldVal: T) => void;
|
|
|
|
export interface WatchOptions {
|
|
deep?: boolean;
|
|
immediate?: boolean;
|
|
}
|
|
|
|
export interface WatchOptionsWithHandler<T> extends WatchOptions {
|
|
handler: WatchHandler<T>;
|
|
}
|
|
|
|
export type DirectiveFunction = (
|
|
el: HTMLElement,
|
|
binding: VNodeDirective,
|
|
vnode: VNode,
|
|
oldVnode: VNode
|
|
) => void;
|
|
|
|
export interface DirectiveOptions {
|
|
bind?: DirectiveFunction;
|
|
inserted?: DirectiveFunction;
|
|
update?: DirectiveFunction;
|
|
componentUpdated?: DirectiveFunction;
|
|
unbind?: DirectiveFunction;
|
|
}
|
|
|
|
export type InjectKey = string | symbol;
|
|
|
|
export type InjectOptions = {
|
|
[key: string]: InjectKey | { from?: InjectKey, default?: any }
|
|
} | string[];
|
|
|