Skip to content

Commit a0a010d

Browse files
authored
fix(types): optional boolean props should have boolean type in return type of defineProps (#7619)
close #7116 fix #5847 fix #7487
1 parent 30399d4 commit a0a010d

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

packages/runtime-core/src/apiSetupHelpers.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@ export function defineProps<
5858
PP extends ComponentObjectPropsOptions = ComponentObjectPropsOptions
5959
>(props: PP): Readonly<ExtractPropTypes<PP>>
6060
// overload 3: typed-based declaration
61-
export function defineProps<TypeProps>(): Readonly<TypeProps>
61+
export function defineProps<TypeProps>(): Readonly<
62+
Omit<TypeProps, BooleanKey<TypeProps>> & {
63+
[K in keyof Pick<TypeProps, BooleanKey<TypeProps>>]-?: NotUndefined<
64+
TypeProps[K]
65+
>
66+
}
67+
>
6268
// implementation
6369
export function defineProps() {
6470
if (__DEV__) {
@@ -128,6 +134,12 @@ export function defineExpose<
128134

129135
type NotUndefined<T> = T extends undefined ? never : T
130136

137+
type BooleanKey<T, K extends keyof T = keyof T> = K extends any
138+
? [T[K]] extends [boolean | undefined]
139+
? K
140+
: never
141+
: never
142+
131143
type InferDefaults<T> = {
132144
[K in keyof T]?: InferDefault<T, NotUndefined<T[K]>>
133145
}
@@ -149,7 +161,6 @@ type PropsWithDefaults<Base, Defaults> = Base & {
149161
: NotUndefined<Base[K]>
150162
: never
151163
}
152-
153164
/**
154165
* Vue `<script setup>` compiler macro for providing props default values when
155166
* using type-based `defineProps` declaration.

test-dts/setupHelpers.test-d.ts

+10
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@ describe('defineProps w/ type declaration', () => {
1313
// type declaration
1414
const props = defineProps<{
1515
foo: string
16+
bool?: boolean
17+
boolAndUndefined: boolean | undefined
1618
}>()
1719
// explicitly declared type should be refined
1820
expectType<string>(props.foo)
1921
// @ts-expect-error
2022
props.bar
23+
24+
expectType<boolean>(props.bool)
25+
expectType<boolean>(props.boolAndUndefined)
2126
})
2227

2328
describe('defineProps w/ type declaration + withDefaults', () => {
@@ -31,6 +36,8 @@ describe('defineProps w/ type declaration + withDefaults', () => {
3136
x?: string
3237
y?: string
3338
z?: string
39+
bool?: boolean
40+
boolAndUndefined: boolean | undefined
3441
}>(),
3542
{
3643
number: 123,
@@ -56,6 +63,9 @@ describe('defineProps w/ type declaration + withDefaults', () => {
5663
expectType<string | undefined>(res.x)
5764
expectType<string | undefined>(res.y)
5865
expectType<string>(res.z)
66+
67+
expectType<boolean>(res.bool)
68+
expectType<boolean>(res.boolAndUndefined)
5969
})
6070

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

0 commit comments

Comments
 (0)