fix(nuxt,schema): merge custom and resolved app configs (#19602)

This commit is contained in:
Daniel Roe 2023-03-11 22:53:28 +00:00 committed by GitHub
parent 3684de58f4
commit 60b4c48eb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 15 deletions

View File

@ -142,17 +142,18 @@ export default defineNuxtModule({
_types +
`
export type CustomAppConfig = Exclude<NuxtCustomSchema['appConfig'], undefined>
type _CustomAppConfig = CustomAppConfig
declare module '@nuxt/schema' {
interface NuxtConfig extends NuxtCustomSchema {}
interface NuxtOptions extends NuxtCustomSchema {}
interface CustomAppConfig extends CustomAppConfig {}
interface NuxtConfig extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface NuxtOptions extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface CustomAppConfig extends _CustomAppConfig {}
}
declare module 'nuxt/schema' {
interface NuxtConfig extends NuxtCustomSchema {}
interface NuxtOptions extends NuxtCustomSchema {}
interface CustomAppConfig extends CustomAppConfig {}
interface NuxtConfig extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface NuxtOptions extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface CustomAppConfig extends _CustomAppConfig {}
}
`
const typesPath = resolve(

View File

@ -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 inlineConfig, [${app.configs.map((_id: string, index: number) => `typeof cfg${index}`).join(', ')}]>
type MergedAppConfig<Resolved extends Record<string, any>, Custom extends Record<string, any>> = {
[K in keyof Resolved]: K extends keyof Custom
? Custom[K] extends Record<string, any>
? Resolved[K] extends Record<string, any>
? MergedAppConfig<Resolved[K], Custom[K]>
: Exclude<Custom[K], undefined>
: Exclude<Custom[K], undefined>
: Resolved[K]
}
declare module 'nuxt/schema' {
interface AppConfig extends ResolvedAppConfig { }
interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { }
}
declare module '@nuxt/schema' {
interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { }
}
`
}

View File

@ -136,7 +136,7 @@ export interface RuntimeConfig extends RuntimeConfigNamespace {
// -- App Config --
export interface CustomAppConfig extends Record<string, any> { }
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 { }

View File

@ -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
}
})

View File

@ -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<AppConfig>().toEqualTypeOf<ExpectedMergedAppConfig>()
})