diff --git a/packages/nuxt/src/core/templates.ts b/packages/nuxt/src/core/templates.ts index a7578a5bec..f1d941aa13 100644 --- a/packages/nuxt/src/core/templates.ts +++ b/packages/nuxt/src/core/templates.ts @@ -222,15 +222,17 @@ declare const inlineConfig = ${JSON.stringify(nuxt.options.appConfig, null, 2)} type ResolvedAppConfig = Defu `typeof cfg${index}`).join(', ')}]> type IsAny = 0 extends 1 & T ? true : false -type MergedAppConfig, Custom extends Record> = { - [K in keyof Resolved]: K extends keyof Custom - ? IsAny extends true +type MergedAppConfig, Custom extends Record> = { + [K in keyof (Resolved & Custom)]: K extends keyof Custom + ? unknown extends Custom[K] ? Resolved[K] - : Custom[K] extends Record - ? Resolved[K] extends Record - ? MergedAppConfig - : Exclude - : Exclude + : IsAny extends true + ? Resolved[K] + : Custom[K] extends Record + ? Resolved[K] extends Record + ? MergedAppConfig + : Exclude + : Exclude : Resolved[K] } diff --git a/packages/schema/src/types/config.ts b/packages/schema/src/types/config.ts index b1e96219e6..f12cf8de76 100644 --- a/packages/schema/src/types/config.ts +++ b/packages/schema/src/types/config.ts @@ -138,7 +138,9 @@ export interface RuntimeConfig extends RuntimeConfigNamespace { // -- App Config -- -export interface CustomAppConfig { } +export interface CustomAppConfig { + [key: string]: unknown +} export interface AppConfigInput extends CustomAppConfig { /** @deprecated reserved */ @@ -158,4 +160,6 @@ export interface NuxtAppConfig { keepalive: boolean | KeepAliveProps } -export interface AppConfig { } +export interface AppConfig { + [key: string]: unknown +} diff --git a/test/fixtures/basic/nuxt.config.ts b/test/fixtures/basic/nuxt.config.ts index cda954f1ae..8377002374 100644 --- a/test/fixtures/basic/nuxt.config.ts +++ b/test/fixtures/basic/nuxt.config.ts @@ -145,6 +145,20 @@ export default defineNuxtConfig({ }, telemetry: false, // for testing telemetry types - it is auto-disabled in tests hooks: { + 'schema:extend' (schemas) { + schemas.push({ + appConfig: { + someThing: { + value: { + $default: 'default', + $schema: { + tsType: 'string | false' + } + } + } + } + }) + }, 'prepare:types' ({ tsConfig }) { tsConfig.include = tsConfig.include!.filter(i => i !== '../../../../**/*') }, diff --git a/test/fixtures/basic/types.ts b/test/fixtures/basic/types.ts index 15985c7496..20ee6a1bbc 100644 --- a/test/fixtures/basic/types.ts +++ b/test/fixtures/basic/types.ts @@ -295,6 +295,10 @@ describe('app config', () => { val: number } userConfig: 123 | 456 + someThing?: { + value?: string | false, + } + [key: string]: unknown } expectTypeOf().toEqualTypeOf() })