diff --git a/packages/nuxt/src/core/schema.ts b/packages/nuxt/src/core/schema.ts index 77fa41f094..ea569c833e 100644 --- a/packages/nuxt/src/core/schema.ts +++ b/packages/nuxt/src/core/schema.ts @@ -142,17 +142,18 @@ export default defineNuxtModule({ _types + ` export type CustomAppConfig = Exclude +type _CustomAppConfig = CustomAppConfig declare module '@nuxt/schema' { - interface NuxtConfig extends NuxtCustomSchema {} - interface NuxtOptions extends NuxtCustomSchema {} - interface CustomAppConfig extends CustomAppConfig {} + interface NuxtConfig extends Omit {} + interface NuxtOptions extends Omit {} + interface CustomAppConfig extends _CustomAppConfig {} } declare module 'nuxt/schema' { - interface NuxtConfig extends NuxtCustomSchema {} - interface NuxtOptions extends NuxtCustomSchema {} - interface CustomAppConfig extends CustomAppConfig {} + interface NuxtConfig extends Omit {} + interface NuxtOptions extends Omit {} + interface CustomAppConfig extends _CustomAppConfig {} } ` const typesPath = resolve( diff --git a/packages/nuxt/src/core/templates.ts b/packages/nuxt/src/core/templates.ts index 76a5aab5fa..c6d70dabad 100644 --- a/packages/nuxt/src/core/templates.ts +++ b/packages/nuxt/src/core/templates.ts @@ -194,14 +194,28 @@ export const appConfigDeclarationTemplate: NuxtTemplate = { filename: 'types/app.config.d.ts', getContents: ({ app, nuxt }) => { return ` +import type { CustomAppConfig } from 'nuxt/schema' import type { Defu } from 'defu' ${app.configs.map((id: string, index: number) => `import ${`cfg${index}`} from ${JSON.stringify(id.replace(/(?<=\w)\.\w+$/g, ''))}`).join('\n')} declare const inlineConfig = ${JSON.stringify(nuxt.options.appConfig, null, 2)} type ResolvedAppConfig = Defu `typeof cfg${index}`).join(', ')}]> +type MergedAppConfig, Custom extends Record> = { + [K in keyof Resolved]: K extends keyof Custom + ? Custom[K] extends Record + ? Resolved[K] extends Record + ? MergedAppConfig + : Exclude + : Exclude + : Resolved[K] +} + declare module 'nuxt/schema' { - interface AppConfig extends ResolvedAppConfig { } + interface AppConfig extends MergedAppConfig { } +} +declare module '@nuxt/schema' { + interface AppConfig extends MergedAppConfig { } } ` } diff --git a/packages/schema/src/types/config.ts b/packages/schema/src/types/config.ts index 047f3cd958..f175e72ed8 100644 --- a/packages/schema/src/types/config.ts +++ b/packages/schema/src/types/config.ts @@ -136,7 +136,7 @@ export interface RuntimeConfig extends RuntimeConfigNamespace { // -- App Config -- -export interface CustomAppConfig extends Record { } +export interface CustomAppConfig { } export interface AppConfigInput extends CustomAppConfig { /** @deprecated reserved */ @@ -156,4 +156,4 @@ export interface NuxtAppConfig { keepalive: boolean | KeepAliveProps } -export interface AppConfig extends CustomAppConfig { } +export interface AppConfig { } diff --git a/test/fixtures/basic/nuxt.schema.ts b/test/fixtures/basic/nuxt.schema.ts index 42ac4eea86..950b325655 100644 --- a/test/fixtures/basic/nuxt.schema.ts +++ b/test/fixtures/basic/nuxt.schema.ts @@ -1,6 +1,10 @@ export default defineNuxtSchema({ appConfig: { - /** This is an example app config defined in custom schema */ + /** + * This is an example app config defined in custom schema + * + * @type {123 | 456} + */ userConfig: 123 } }) diff --git a/test/fixtures/basic/types.ts b/test/fixtures/basic/types.ts index f73856d7c1..b0f22dffcc 100644 --- a/test/fixtures/basic/types.ts +++ b/test/fixtures/basic/types.ts @@ -246,13 +246,12 @@ describe('composables', () => { describe('app config', () => { it('merges app config as expected', () => { interface ExpectedMergedAppConfig { - fromLayer: boolean, - fromNuxtConfig: boolean, + fromLayer: boolean + fromNuxtConfig: boolean nested: { val: number - }, - userConfig: number - [key: string]: any + } + userConfig: 123 | 456 } expectTypeOf().toEqualTypeOf() })