Skip to content

Commit d09f791

Browse files
committed
fix(types): retain union type narrowing in PropsWithDefaults with defaults applied
1 parent b094c72 commit d09f791

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

packages-private/dts-test/setupHelpers.test-d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ describe('defineProps w/ type declaration + withDefaults', <T extends
5858
bool?: boolean
5959
boolAndUndefined: boolean | undefined
6060
foo?: T
61+
u:
62+
| { type: 'button'; buttonType?: 'submit' }
63+
| { type: 'link'; href: string }
6164
}>(),
6265
{
6366
number: 123,
@@ -88,6 +91,13 @@ describe('defineProps w/ type declaration + withDefaults', <T extends
8891

8992
expectType<boolean>(res.bool)
9093
expectType<boolean>(res.boolAndUndefined)
94+
95+
if (res.u.type === 'button') {
96+
expectType<'submit' | undefined>(res.u.buttonType)
97+
}
98+
if (res.u.type === 'link') {
99+
expectType<string>(res.u.href)
100+
}
91101
})
92102

93103
describe('defineProps w/ union type declaration + withDefaults', () => {

packages/runtime-core/src/apiSetupHelpers.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -331,21 +331,23 @@ type PropsWithDefaults<
331331
T,
332332
Defaults extends InferDefaults<T>,
333333
BKeys extends keyof T,
334-
> = Readonly<MappedOmit<T, keyof Defaults>> & {
335-
readonly [K in keyof Defaults as K extends keyof T
336-
? K
337-
: never]-?: K extends keyof T
338-
? Defaults[K] extends undefined
339-
? IfAny<Defaults[K], NotUndefined<T[K]>, T[K]>
340-
: NotUndefined<T[K]>
341-
: never
342-
} & {
343-
readonly [K in BKeys]-?: K extends keyof Defaults
344-
? Defaults[K] extends undefined
345-
? boolean | undefined
346-
: boolean
347-
: boolean
348-
}
334+
> = T extends unknown
335+
? Readonly<MappedOmit<T, keyof Defaults>> & {
336+
readonly [K in keyof Defaults as K extends keyof T
337+
? K
338+
: never]-?: K extends keyof T
339+
? Defaults[K] extends undefined
340+
? IfAny<Defaults[K], NotUndefined<T[K]>, T[K]>
341+
: NotUndefined<T[K]>
342+
: never
343+
} & {
344+
readonly [K in BKeys]-?: K extends keyof Defaults
345+
? Defaults[K] extends undefined
346+
? boolean | undefined
347+
: boolean
348+
: boolean
349+
}
350+
: never
349351

350352
/**
351353
* Vue `<script setup>` compiler macro for providing props default values when

0 commit comments

Comments
 (0)