import { Vue, CreateElement, CombinedVueInstance } from './vue' import { VNode, VNodeData, VNodeDirective, NormalizedScopedSlot } from './vnode' import { SetupContext } from './v3-setup-context' import { DebuggerEvent } from './v3-generated' type Constructor = { new (...args: any[]): any } // we don't support infer props in async component // N.B. ComponentOptions is contravariant, the default generic should be bottom type export type Component< Data = DefaultData, Methods = DefaultMethods, Computed = DefaultComputed, Props = DefaultProps, SetupBindings = {} > = | typeof Vue | FunctionalComponentOptions | ComponentOptions type EsModule = T | { default: T } type ImportedComponent< Data = DefaultData, Methods = DefaultMethods, Computed = DefaultComputed, Props = DefaultProps, SetupBindings = {} > = EsModule> export type AsyncComponent< Data = DefaultData, Methods = DefaultMethods, Computed = DefaultComputed, Props = DefaultProps, SetupBindings = {} > = | AsyncComponentPromise | AsyncComponentFactory export type AsyncComponentPromise< Data = DefaultData, Methods = DefaultMethods, Computed = DefaultComputed, Props = DefaultProps, SetupBindings = {} > = ( resolve: ( component: Component ) => void, reject: (reason?: any) => void ) => Promise< ImportedComponent > | void export type AsyncComponentFactory< Data = DefaultData, Methods = DefaultMethods, Computed = DefaultComputed, Props = DefaultProps, SetupBindings = {} > = () => { component: Promise< ImportedComponent > loading?: ImportedComponent error?: ImportedComponent delay?: number timeout?: number } /** * 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` and work backwards. */ export type Accessors = { [K in keyof T]: (() => T[K]) | ComputedOptions } type DataDef = Data | ((this: Readonly & 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, SetupBindings > = object & ComponentOptions< V, DataDef, V>, Methods, Computed, PropNames[], Record, SetupBindings > & ThisType< CombinedVueInstance< V, Data, Methods, Computed, Readonly>, SetupBindings > > /** * 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, SetupBindings > = object & ComponentOptions< V, DataDef, Methods, Computed, RecordPropsDefinition, Props, SetupBindings > & ThisType< CombinedVueInstance< V, Data, Methods, Computed, Readonly, SetupBindings > > type DefaultData = object | ((this: V) => object) type DefaultProps = Record type DefaultMethods = { [key: string]: (this: V, ...args: any[]) => any } type DefaultComputed = { [key: string]: any } export interface ComponentOptions< V extends Vue, Data = DefaultData, Methods = DefaultMethods, Computed = DefaultComputed, PropsDef = PropsDefinition, Props = DefaultProps, RawBindings = {} > { data?: Data props?: PropsDef propsData?: object computed?: Accessors methods?: Methods watch?: Record | WatchHandler> setup?: ( this: void, props: Props, ctx: SetupContext ) => Promise | RawBindings | ((h: CreateElement) => VNode) | void el?: Element | string template?: string // hack is for functional component type inference, should not be used in user code render?(createElement: CreateElement, hack: RenderContext): VNode renderError?(createElement: CreateElement, 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 serverPrefetch?(this: V): Promise renderTracked?(e: DebuggerEvent): void renderTriggerd?(e: DebuggerEvent): void directives?: { [key: string]: DirectiveFunction | DirectiveOptions } components?: { [key: string]: | Component | AsyncComponent } transitions?: { [key: string]: object } filters?: { [key: string]: Function } provide?: object | (() => object) inject?: InjectOptions model?: { prop?: string event?: string } parent?: Vue mixins?: (ComponentOptions | typeof Vue)[] name?: string // TODO: support properly inferred 'extends' extends?: ComponentOptions | typeof Vue delimiters?: [string, string] comments?: boolean inheritAttrs?: boolean } export interface FunctionalComponentOptions< Props = DefaultProps, PropDefs = PropsDefinition > { name?: string props?: PropDefs model?: { prop?: string event?: string } inject?: InjectOptions functional: boolean render?( this: undefined, createElement: CreateElement, context: RenderContext ): VNode | VNode[] } export interface RenderContext { props: Props children: VNode[] slots(): any data: VNodeData parent: Vue listeners: { [key: string]: Function | Function[] } scopedSlots: { [key: string]: NormalizedScopedSlot } injections: any } export type Prop = | { (): T } | { new (...args: never[]): T & object } | { new (...args: string[]): Function } export type PropType = Prop | Prop[] export type PropValidator = PropOptions | PropType export interface PropOptions { type?: PropType required?: boolean default?: T | null | undefined | (() => T | null | undefined) validator?(value: unknown): boolean } export type RecordPropsDefinition = { [K in keyof T]: PropValidator } export type ArrayPropsDefinition = (keyof T)[] export type PropsDefinition = | ArrayPropsDefinition | RecordPropsDefinition export interface ComputedOptions { get?(): T set?(value: T): void cache?: boolean } export type WatchHandler = string | ((val: T, oldVal: T) => void) export interface WatchOptions { deep?: boolean immediate?: boolean } export interface WatchOptionsWithHandler extends WatchOptions { handler: WatchHandler } export interface DirectiveBinding extends Readonly { readonly modifiers: { [key: string]: boolean } } export type DirectiveFunction = ( el: HTMLElement, binding: DirectiveBinding, 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[]