Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(types): support nuxt types for defineComponent #19789

Merged
merged 4 commits into from Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
>
>