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 + _types +
` `
export type CustomAppConfig = Exclude<NuxtCustomSchema['appConfig'], undefined> export type CustomAppConfig = Exclude<NuxtCustomSchema['appConfig'], undefined>
type _CustomAppConfig = CustomAppConfig
declare module '@nuxt/schema' { declare module '@nuxt/schema' {
interface NuxtConfig extends NuxtCustomSchema {} interface NuxtConfig extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface NuxtOptions extends NuxtCustomSchema {} interface NuxtOptions extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface CustomAppConfig extends CustomAppConfig {} interface CustomAppConfig extends _CustomAppConfig {}
} }
declare module 'nuxt/schema' { declare module 'nuxt/schema' {
interface NuxtConfig extends NuxtCustomSchema {} interface NuxtConfig extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface NuxtOptions extends NuxtCustomSchema {} interface NuxtOptions extends Omit<NuxtCustomSchema, 'appConfig'> {}
interface CustomAppConfig extends CustomAppConfig {} interface CustomAppConfig extends _CustomAppConfig {}
} }
` `
const typesPath = resolve( const typesPath = resolve(

View File

@ -194,14 +194,28 @@ export const appConfigDeclarationTemplate: NuxtTemplate = {
filename: 'types/app.config.d.ts', filename: 'types/app.config.d.ts',
getContents: ({ app, nuxt }) => { getContents: ({ app, nuxt }) => {
return ` return `
import type { CustomAppConfig } from 'nuxt/schema'
import type { Defu } from 'defu' 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')} ${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)} 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 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' { 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 -- // -- App Config --
export interface CustomAppConfig extends Record<string, any> { } export interface CustomAppConfig { }
export interface AppConfigInput extends CustomAppConfig { export interface AppConfigInput extends CustomAppConfig {
/** @deprecated reserved */ /** @deprecated reserved */
@ -156,4 +156,4 @@ export interface NuxtAppConfig {
keepalive: boolean | KeepAliveProps keepalive: boolean | KeepAliveProps
} }
export interface AppConfig extends CustomAppConfig { } export interface AppConfig { }

View File

@ -1,6 +1,10 @@
export default defineNuxtSchema({ export default defineNuxtSchema({
appConfig: { 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 userConfig: 123
} }
}) })

View File

@ -246,13 +246,12 @@ describe('composables', () => {
describe('app config', () => { describe('app config', () => {
it('merges app config as expected', () => { it('merges app config as expected', () => {
interface ExpectedMergedAppConfig { interface ExpectedMergedAppConfig {
fromLayer: boolean, fromLayer: boolean
fromNuxtConfig: boolean, fromNuxtConfig: boolean
nested: { nested: {
val: number val: number
}, }
userConfig: number userConfig: 123 | 456
[key: string]: any
} }
expectTypeOf<AppConfig>().toEqualTypeOf<ExpectedMergedAppConfig>() expectTypeOf<AppConfig>().toEqualTypeOf<ExpectedMergedAppConfig>()
}) })