From 2864d875793da3026ee41cdb69dd75fd6134a757 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Tue, 4 May 2021 09:17:53 -0500 Subject: [PATCH 1/4] Add types to allow `asyncData` to be used --- packages/types/app/vue.d.ts | 97 +++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/packages/types/app/vue.d.ts b/packages/types/app/vue.d.ts index 116059648e5d..4a418db6bf38 100644 --- a/packages/types/app/vue.d.ts +++ b/packages/types/app/vue.d.ts @@ -5,14 +5,32 @@ import Vue from 'vue' import { MetaInfo } from 'vue-meta' import { Route } from 'vue-router' +import { RecordPropsDefinition, PropsDefinition, ComponentOptions } from 'vue/types/options' +import { CombinedVueInstance, ExtendedVue } from 'vue/types/vue' import { NuxtRuntimeConfig } from '../config/runtime' import { Context, Middleware, Transition, NuxtApp } from './index' +type DefaultData = object | ((this: V) => object); +type DefaultProps = Record; +type DefaultMethods = { [key: string]: (this: V, ...args: any[]) => any }; +type DefaultComputed = { [key: string]: any }; +type DefaultAsyncData = + ((this: V, context: Context) => Promise | object | void); + declare module 'vue/types/options' { - // eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars - interface ComponentOptions { + interface ComponentOptions< + V extends Vue, + /* eslint-disable no-unused-vars,@typescript-eslint/no-unused-vars */ + Data = DefaultData, + Methods = DefaultMethods, + Computed = DefaultComputed, + PropsDef = PropsDefinition, + Props = DefaultProps, + /* eslint-enable no-unused-vars,@typescript-eslint/no-unused-vars */ + AsyncData = DefaultAsyncData + > { // eslint-disable-next-line @typescript-eslint/ban-types - asyncData?(ctx: Context): Promise | object | void + asyncData?: AsyncData fetch?(ctx: Context): Promise | void fetchKey?: string | ((getKey: (id: string) => number) => string) fetchDelay?: number @@ -30,6 +48,57 @@ declare module 'vue/types/options' { } } +type DataDef = Data | ((this: Readonly & V) => Data); +type Awaited = T extends PromiseLike ? Awaited : T; + +type ThisTypedComponentOptionsWithArrayPropsAndAsyncData< + V extends Vue, + Data, + Methods, + Computed, + PropNames extends string, + AsyncData + > = object & + ComponentOptions< + V, + DataDef, V>, + Methods, + Computed, + PropNames[], + Record, + DataDef + > & + ThisType< + CombinedVueInstance< + V, + Data, + Methods, + Computed, + Readonly> + > & + Awaited + >; +export type ThisTypedComponentOptionsWithRecordPropsAndAsyncData< + V extends Vue, + Data, + Methods, + Computed, + Props, + AsyncData + > = object & + ComponentOptions< + V, + DataDef, + Methods, + Computed, + RecordPropsDefinition, + Props, + DataDef + > & + ThisType< + CombinedVueInstance> & Awaited + >; + declare module 'vue/types/vue' { interface Vue { $config: NuxtRuntimeConfig @@ -41,4 +110,26 @@ declare module 'vue/types/vue' { timestamp: number } } + interface VueConstructor { + extend( + options?: ThisTypedComponentOptionsWithArrayPropsAndAsyncData< + V, + Data, + Methods, + Computed, + PropNames, + AsyncData + > + ): ExtendedVue>; + extend( + options?: ThisTypedComponentOptionsWithRecordPropsAndAsyncData< + V, + Data, + Methods, + Computed, + Props, + AsyncData + > + ): ExtendedVue; + } } From 50919b44620180edb0b537c85f09a282c1aaad3b Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 5 May 2021 21:09:12 +0100 Subject: [PATCH 2/4] feat(types): merge types for data/asyncdata where both are present --- packages/types/app/vue.d.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/types/app/vue.d.ts b/packages/types/app/vue.d.ts index 4a418db6bf38..fc16945c639a 100644 --- a/packages/types/app/vue.d.ts +++ b/packages/types/app/vue.d.ts @@ -50,6 +50,9 @@ declare module 'vue/types/options' { type DataDef = Data | ((this: Readonly & V) => Data); type Awaited = T extends PromiseLike ? Awaited : T; +type Merged = { + [key in keyof Data | keyof AsyncData]: key extends keyof Data ? key extends keyof AsyncData ? NonNullable | AsyncData[key] : Data[key] : key extends keyof AsyncData ? AsyncData[key] : never +} type ThisTypedComponentOptionsWithArrayPropsAndAsyncData< V extends Vue, @@ -71,12 +74,11 @@ type ThisTypedComponentOptionsWithArrayPropsAndAsyncData< ThisType< CombinedVueInstance< V, - Data, + Merged>, Methods, Computed, Readonly> - > & - Awaited + > >; export type ThisTypedComponentOptionsWithRecordPropsAndAsyncData< V extends Vue, @@ -94,9 +96,9 @@ export type ThisTypedComponentOptionsWithRecordPropsAndAsyncData< RecordPropsDefinition, Props, DataDef - > & +> & ThisType< - CombinedVueInstance> & Awaited + CombinedVueInstance>, Methods, Computed, Readonly> >; declare module 'vue/types/vue' { From a5ad7418fd470df6a4d6dea53e82f135208066f6 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 5 May 2021 21:12:38 +0100 Subject: [PATCH 3/4] style: cleanup stray semicolons and indentation --- packages/types/app/vue.d.ts | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/types/app/vue.d.ts b/packages/types/app/vue.d.ts index fc16945c639a..f0211273f6aa 100644 --- a/packages/types/app/vue.d.ts +++ b/packages/types/app/vue.d.ts @@ -10,12 +10,11 @@ import { CombinedVueInstance, ExtendedVue } from 'vue/types/vue' import { NuxtRuntimeConfig } from '../config/runtime' import { Context, Middleware, Transition, NuxtApp } from './index' -type DefaultData = object | ((this: V) => object); -type DefaultProps = Record; -type DefaultMethods = { [key: string]: (this: V, ...args: any[]) => any }; -type DefaultComputed = { [key: string]: any }; -type DefaultAsyncData = - ((this: V, context: Context) => Promise | object | void); +type DefaultData = object | ((this: V) => object) +type DefaultProps = Record +type DefaultMethods = { [key: string]: (this: V, ...args: any[]) => any } +type DefaultComputed = { [key: string]: any } +type DefaultAsyncData = ((this: V, context: Context) => Promise | object | void) declare module 'vue/types/options' { interface ComponentOptions< @@ -28,7 +27,7 @@ declare module 'vue/types/options' { Props = DefaultProps, /* eslint-enable no-unused-vars,@typescript-eslint/no-unused-vars */ AsyncData = DefaultAsyncData - > { + > { // eslint-disable-next-line @typescript-eslint/ban-types asyncData?: AsyncData fetch?(ctx: Context): Promise | void @@ -48,8 +47,8 @@ declare module 'vue/types/options' { } } -type DataDef = Data | ((this: Readonly & V) => Data); -type Awaited = T extends PromiseLike ? Awaited : T; +type DataDef = Data | ((this: Readonly & V) => Data) +type Awaited = T extends PromiseLike ? Awaited : T type Merged = { [key in keyof Data | keyof AsyncData]: key extends keyof Data ? key extends keyof AsyncData ? NonNullable | AsyncData[key] : Data[key] : key extends keyof AsyncData ? AsyncData[key] : never } @@ -61,7 +60,7 @@ type ThisTypedComponentOptionsWithArrayPropsAndAsyncData< Computed, PropNames extends string, AsyncData - > = object & +> = object & ComponentOptions< V, DataDef, V>, @@ -70,7 +69,7 @@ type ThisTypedComponentOptionsWithArrayPropsAndAsyncData< PropNames[], Record, DataDef - > & + > & ThisType< CombinedVueInstance< V, @@ -78,8 +77,8 @@ type ThisTypedComponentOptionsWithArrayPropsAndAsyncData< Methods, Computed, Readonly> - > - >; + > + > export type ThisTypedComponentOptionsWithRecordPropsAndAsyncData< V extends Vue, Data, @@ -87,7 +86,7 @@ export type ThisTypedComponentOptionsWithRecordPropsAndAsyncData< Computed, Props, AsyncData - > = object & +> = object & ComponentOptions< V, DataDef, @@ -99,7 +98,7 @@ export type ThisTypedComponentOptionsWithRecordPropsAndAsyncData< > & ThisType< CombinedVueInstance>, Methods, Computed, Readonly> - >; + > declare module 'vue/types/vue' { interface Vue { @@ -121,8 +120,8 @@ declare module 'vue/types/vue' { Computed, PropNames, AsyncData - > - ): ExtendedVue>; + > + ): ExtendedVue> extend( options?: ThisTypedComponentOptionsWithRecordPropsAndAsyncData< V, @@ -131,7 +130,7 @@ declare module 'vue/types/vue' { Computed, Props, AsyncData - > - ): ExtendedVue; + > + ): ExtendedVue } } From 694091125b63df47b233c120abfc5fc1c4a200d3 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 5 May 2021 21:12:57 +0100 Subject: [PATCH 4/4] docs: add comment for source of types --- packages/types/app/vue.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/types/app/vue.d.ts b/packages/types/app/vue.d.ts index f0211273f6aa..4aad87a1289e 100644 --- a/packages/types/app/vue.d.ts +++ b/packages/types/app/vue.d.ts @@ -10,6 +10,7 @@ import { CombinedVueInstance, ExtendedVue } from 'vue/types/vue' import { NuxtRuntimeConfig } from '../config/runtime' import { Context, Middleware, Transition, NuxtApp } from './index' +// https://github.com/vuejs/vue/blob/dev/types/options.d.ts#L63-L66 type DefaultData = object | ((this: V) => object) type DefaultProps = Record type DefaultMethods = { [key: string]: (this: V, ...args: any[]) => any }