Skip to content

Commit dd0d13d

Browse files
authored
fix(nuxt): improved typing support for app config (#20526)
1 parent a21a520 commit dd0d13d

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

packages/nuxt/src/core/templates.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,17 @@ declare const inlineConfig = ${JSON.stringify(nuxt.options.appConfig, null, 2)}
222222
type ResolvedAppConfig = Defu<typeof inlineConfig, [${app.configs.map((_id: string, index: number) => `typeof cfg${index}`).join(', ')}]>
223223
type IsAny<T> = 0 extends 1 & T ? true : false
224224
225-
type MergedAppConfig<Resolved extends Record<string, any>, Custom extends Record<string, any>> = {
226-
[K in keyof Resolved]: K extends keyof Custom
227-
? IsAny<Custom[K]> extends true
225+
type MergedAppConfig<Resolved extends Record<string, unknown>, Custom extends Record<string, unknown>> = {
226+
[K in keyof (Resolved & Custom)]: K extends keyof Custom
227+
? unknown extends Custom[K]
228228
? Resolved[K]
229-
: Custom[K] extends Record<string, any>
230-
? Resolved[K] extends Record<string, any>
231-
? MergedAppConfig<Resolved[K], Custom[K]>
232-
: Exclude<Custom[K], undefined>
233-
: Exclude<Custom[K], undefined>
229+
: IsAny<Custom[K]> extends true
230+
? Resolved[K]
231+
: Custom[K] extends Record<string, any>
232+
? Resolved[K] extends Record<string, any>
233+
? MergedAppConfig<Resolved[K], Custom[K]>
234+
: Exclude<Custom[K], undefined>
235+
: Exclude<Custom[K], undefined>
234236
: Resolved[K]
235237
}
236238

packages/schema/src/types/config.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ export interface RuntimeConfig extends RuntimeConfigNamespace {
138138

139139
// -- App Config --
140140

141-
export interface CustomAppConfig { }
141+
export interface CustomAppConfig {
142+
[key: string]: unknown
143+
}
142144

143145
export interface AppConfigInput extends CustomAppConfig {
144146
/** @deprecated reserved */
@@ -158,4 +160,6 @@ export interface NuxtAppConfig {
158160
keepalive: boolean | KeepAliveProps
159161
}
160162

161-
export interface AppConfig { }
163+
export interface AppConfig {
164+
[key: string]: unknown
165+
}

test/fixtures/basic/nuxt.config.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,20 @@ export default defineNuxtConfig({
145145
},
146146
telemetry: false, // for testing telemetry types - it is auto-disabled in tests
147147
hooks: {
148+
'schema:extend' (schemas) {
149+
schemas.push({
150+
appConfig: {
151+
someThing: {
152+
value: {
153+
$default: 'default',
154+
$schema: {
155+
tsType: 'string | false'
156+
}
157+
}
158+
}
159+
}
160+
})
161+
},
148162
'prepare:types' ({ tsConfig }) {
149163
tsConfig.include = tsConfig.include!.filter(i => i !== '../../../../**/*')
150164
},

test/fixtures/basic/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,10 @@ describe('app config', () => {
295295
val: number
296296
}
297297
userConfig: 123 | 456
298+
someThing?: {
299+
value?: string | false,
300+
}
301+
[key: string]: unknown
298302
}
299303
expectTypeOf<AppConfig>().toEqualTypeOf<ExpectedMergedAppConfig>()
300304
})

0 commit comments

Comments
 (0)