Skip to content

Commit

Permalink
feat(types): support nuxt types for defineComponent (#19789)
Browse files Browse the repository at this point in the history
  • Loading branch information
rchl committed Mar 20, 2023
1 parent d5cda14 commit 4b6a504
Show file tree
Hide file tree
Showing 2 changed files with 436 additions and 11 deletions.
278 changes: 268 additions & 10 deletions packages/types/app/vue.d.ts
Expand Up @@ -6,7 +6,12 @@ import type Vue from 'vue'
import type { MetaInfo } from 'vue-meta'
import type { Route } from 'vue-router'
import type { RecordPropsDefinition, ComponentOptions } from 'vue/types/options'
import type { ComponentOptionsMixin } from 'vue/types/v3-component-options'
import type { Data, HasDefined } from 'vue/types/common'
import type { ComponentOptionsMixin, ComputedOptions, ComponentOptionsBase, MethodOptions } from 'vue/types/v3-component-options'
import type { ComponentPropsOptions, ExtractDefaultPropTypes, ExtractPropTypes } from 'vue/types/v3-component-props'
import type { CreateComponentPublicInstance } from 'vue/types/v3-component-public-instance'
import type { DefineComponent } from 'vue/types/v3-define-component'
import type { EmitsOptions } from 'vue/types/v3-setup-context'
import type { CombinedVueInstance } from 'vue/types/vue'
import type { NuxtRuntimeConfig } from '../config/runtime'
import type { Context, Middleware, Transition, NuxtApp } from './index'
Expand All @@ -16,12 +21,150 @@ 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 }
type DefaultAsyncData<V> = ((this: V, context: Context) => Promise<object | void> | object | void)
type DefaultAsyncData = ((this: never, context: Context) => Promise<object | void> | object | void)

declare module 'vue/types' {
/**
* overload 1: object format with no props
*/
export function defineComponent<
RawBindings,
D = {},
C extends ComputedOptions = {},
M extends MethodOptions = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
Emits extends EmitsOptions = {},
EmitsNames extends string = string,
AsyncData extends DefaultAsyncData = DefaultAsyncData,
>(
options: { functional?: never } & ComponentOptionsWithoutPropsAndWithAsyncData<
{},
RawBindings,
D,
C,
M,
Mixin,
Extends,
Emits,
EmitsNames,
AsyncData
>
): DefineComponent<
{},
RawBindings,
Merged<D, Awaited<ReturnType<AsyncData>>>,
C,
M,
Mixin,
Extends,
Emits
>

/**
* overload 2: object format with array props declaration
* props inferred as `{ [key in PropNames]?: any }`
*
* return type is for Vetur and TSX support
*/
export function defineComponent<
PropNames extends string,
RawBindings = {},
D = {},
C extends ComputedOptions = {},
M extends MethodOptions = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
Emits extends EmitsOptions = {},
EmitsNames extends string = string,
PropsOptions extends ComponentPropsOptions = ComponentPropsOptions,
AsyncData extends DefaultAsyncData = DefaultAsyncData,
>(
options: { functional?: never } & ComponentOptionsWithArrayPropsAndAsyncData<
PropNames,
RawBindings,
D,
C,
M,
Mixin,
Extends,
Emits,
EmitsNames,
Readonly<{ [key in PropNames]?: any }>,
AsyncData
>
): DefineComponent<
Readonly<{ [key in PropNames]?: any }>,
RawBindings,
Merged<D, Awaited<ReturnType<AsyncData>>>,
C,
M,
Mixin,
Extends,
Emits
>

/**
* overload 3: object format with object props declaration
*
* see `ExtractPropTypes` in './componentProps.ts'
*/
export function defineComponent<
Props,
RawBindings = {},
D = {},
C extends ComputedOptions = {},
M extends MethodOptions = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
Emits extends EmitsOptions = {},
EmitsNames extends string = string,
PropsOptions extends ComponentPropsOptions = ComponentPropsOptions,
AsyncData extends DefaultAsyncData = DefaultAsyncData,
>(
options: HasDefined<Props> extends true
? { functional?: never } & ComponentOptionsWithPropsAndAsyncData<
PropsOptions,
RawBindings,
D,
C,
M,
Mixin,
Extends,
Emits,
EmitsNames,
Props,
ExtractDefaultPropTypes<PropsOptions>,
AsyncData
>
: { functional?: never } & ComponentOptionsWithPropsAndAsyncData<
PropsOptions,
RawBindings,
D,
C,
M,
Mixin,
Extends,
Emits,
EmitsNames,
ExtractPropTypes<PropsOptions>,
AsyncData
>
): DefineComponent<
PropsOptions,
RawBindings,
Merged<D, Awaited<ReturnType<AsyncData>>>,
C,
M,
Mixin,
Extends,
Emits
>
}

declare module 'vue/types/options' {
interface ComponentOptions<
V extends Vue,
/* eslint-disable no-unused-vars,@typescript-eslint/no-unused-vars */
Data = DefaultData<V>,
Methods = DefaultMethods<V>,
Computed = DefaultComputed,
Expand All @@ -30,10 +173,8 @@ declare module 'vue/types/options' {
RawBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
/* eslint-enable no-unused-vars,@typescript-eslint/no-unused-vars */
AsyncData = DefaultAsyncData<V>
AsyncData = DefaultAsyncData
> {
// eslint-disable-next-line @typescript-eslint/ban-types
asyncData?: AsyncData
fetch?(ctx: Context): Promise<void> | void
fetchKey?: string | ((getKey: (id: string) => number) => string)
Expand Down Expand Up @@ -67,7 +208,7 @@ type ThisTypedComponentOptionsWithArrayPropsAndAsyncData<
SetupBindings,
Mixin extends ComponentOptionsMixin,
Extends extends ComponentOptionsMixin,
AsyncData extends DefaultAsyncData<V> = DefaultAsyncData<V>
AsyncData extends DefaultAsyncData = DefaultAsyncData
> = object &
ComponentOptions<
V,
Expand Down Expand Up @@ -102,7 +243,7 @@ export type ThisTypedComponentOptionsWithRecordPropsAndAsyncData<
SetupBindings,
Mixin extends ComponentOptionsMixin,
Extends extends ComponentOptionsMixin,
AsyncData extends DefaultAsyncData<V>
AsyncData extends DefaultAsyncData
> = object &
ComponentOptions<
V,
Expand Down Expand Up @@ -151,7 +292,7 @@ declare module 'vue/types/vue' {
SetupBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
AsyncData extends DefaultAsyncData<V> = DefaultAsyncData<V>
AsyncData extends DefaultAsyncData = DefaultAsyncData
>(
options?: ThisTypedComponentOptionsWithArrayPropsAndAsyncData<
V,
Expand Down Expand Up @@ -184,7 +325,7 @@ declare module 'vue/types/vue' {
SetupBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
AsyncData extends DefaultAsyncData<V> = DefaultAsyncData<V>
AsyncData extends DefaultAsyncData = DefaultAsyncData
>(
options?: ThisTypedComponentOptionsWithRecordPropsAndAsyncData<
V,
Expand All @@ -209,3 +350,120 @@ declare module 'vue/types/vue' {
>
}
}

export type ComponentOptionsWithPropsAndAsyncData<
PropsOptions = ComponentPropsOptions,
RawBindings = Data,
D = Data,
C extends ComputedOptions = {},
M extends MethodOptions = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
Emits extends EmitsOptions = {},
EmitsNames extends string = string,
Props = ExtractPropTypes<PropsOptions>,
Defaults = ExtractDefaultPropTypes<PropsOptions>,
AsyncData extends DefaultAsyncData = DefaultAsyncData,
> = ComponentOptionsBase<
Props,
RawBindings,
D,
C,
M,
Mixin,
Extends,
Emits,
EmitsNames,
Defaults
> & {
props?: PropsOptions,
asyncData: AsyncData,
} & ThisType<
CreateComponentPublicInstance<
Props,
RawBindings,
Merged<D, Awaited<ReturnType<AsyncData>>>,
C,
M,
Mixin,
Extends,
Emits
>
>

export type ComponentOptionsWithArrayPropsAndAsyncData<
PropNames extends string = string,
RawBindings = Data,
D = Data,
C extends ComputedOptions = {},
M extends MethodOptions = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
Emits extends EmitsOptions = {},
EmitsNames extends string = string,
Props = Readonly<{ [key in PropNames]?: any }>,
AsyncData extends DefaultAsyncData = DefaultAsyncData,
> = ComponentOptionsBase<
Props,
RawBindings,
D,
C,
M,
Mixin,
Extends,
Emits,
EmitsNames,
{}
> & {
props?: PropNames[],
asyncData: AsyncData,
} & ThisType<
CreateComponentPublicInstance<
Props,
RawBindings,
Merged<D, Awaited<ReturnType<AsyncData>>>,
C,
M,
Mixin,
Extends,
Emits
>
>

export type ComponentOptionsWithoutPropsAndWithAsyncData<
Props = {},
RawBindings = Data,
D = Data,
C extends ComputedOptions = {},
M extends MethodOptions = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
Emits extends EmitsOptions = {},
EmitsNames extends string = string,
AsyncData extends DefaultAsyncData = DefaultAsyncData,
> = ComponentOptionsBase<
Props,
RawBindings,
D,
C,
M,
Mixin,
Extends,
Emits,
EmitsNames,
{}
> & {
props?: undefined,
asyncData: AsyncData,
} & ThisType<
CreateComponentPublicInstance<
Props,
RawBindings,
Merged<D, Awaited<ReturnType<AsyncData>>>,
C,
M,
Mixin,
Extends,
Emits
>
>

0 comments on commit 4b6a504

Please sign in to comment.