type AnyConfig, U extends Record> = { [V in keyof U]: V extends keyof T ? U[V] extends (...args: any[]) => any ? (argv: T[V]) => T[V] : T[V] : U[V] } type CalculatedConfig, U extends Record> = T & { [V in keyof U]: V extends keyof T ? T[V] : U[V] } export default function mergeConfig< T extends Record, U extends Record >(defaultConfig: T, ...configs: (AnyConfig | null | undefined)[]) { const ret = { ...defaultConfig } as Partial> configs.forEach((config) => { if (!config) return ;(Object.keys(config) as (keyof typeof config)[]).forEach((key) => { const val = config[key] if (typeof val === 'function') { ret[key] = val(ret[key]) } else { ret[key] = val as CalculatedConfig[typeof key] } }) }) return ret as CalculatedConfig }