diff --git a/packages-private/dts-test/setupHelpers.test-d.ts b/packages-private/dts-test/setupHelpers.test-d.ts index 4074176ff98..7b5d6f147f0 100644 --- a/packages-private/dts-test/setupHelpers.test-d.ts +++ b/packages-private/dts-test/setupHelpers.test-d.ts @@ -240,6 +240,23 @@ describe('withDefaults w/ defineProp type is different from the defaults type', res1.value }) +describe('withDefaults w/ defineProp discriminate union type', () => { + const props = withDefaults( + defineProps< + { type: 'button'; buttonType?: 'submit' } | { type: 'link'; href: string } + >(), + { + type: 'button', + }, + ) + if (props.type === 'button') { + expectType<'submit' | undefined>(props.buttonType) + } + if (props.type === 'link') { + expectType(props.href) + } +}) + describe('defineProps w/ runtime declaration', () => { // runtime declaration const props = defineProps({ diff --git a/packages/runtime-core/src/apiSetupHelpers.ts b/packages/runtime-core/src/apiSetupHelpers.ts index 33817818a93..54712c6807a 100644 --- a/packages/runtime-core/src/apiSetupHelpers.ts +++ b/packages/runtime-core/src/apiSetupHelpers.ts @@ -331,21 +331,23 @@ type PropsWithDefaults< T, Defaults extends InferDefaults, BKeys extends keyof T, -> = Readonly> & { - readonly [K in keyof Defaults as K extends keyof T - ? K - : never]-?: K extends keyof T - ? Defaults[K] extends undefined - ? IfAny, T[K]> - : NotUndefined - : never -} & { - readonly [K in BKeys]-?: K extends keyof Defaults - ? Defaults[K] extends undefined - ? boolean | undefined - : boolean - : boolean -} +> = T extends unknown + ? Readonly> & { + readonly [K in keyof Defaults as K extends keyof T + ? K + : never]-?: K extends keyof T + ? Defaults[K] extends undefined + ? IfAny, T[K]> + : NotUndefined + : never + } & { + readonly [K in BKeys]-?: K extends keyof Defaults + ? Defaults[K] extends undefined + ? boolean | undefined + : boolean + : boolean + } + : never /** * Vue `