Skip to content

Commit c288c7b

Browse files
committed
fix(types): ensure defineProps with generics return correct types
1 parent f61499d commit c288c7b

File tree

2 files changed

+25
-15
lines changed

2 files changed

+25
-15
lines changed

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

+10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ describe('defineProps w/ type declaration', () => {
2424
expectType<boolean>(props.boolAndUndefined)
2525
})
2626

27+
describe('defineProps w/ generics', () => {
28+
function test<T extends boolean>() {
29+
const props = defineProps<{ foo: T; bar: string; x?: boolean }>()
30+
expectType<T>(props.foo)
31+
expectType<string>(props.bar)
32+
expectType<boolean>(props.x)
33+
}
34+
test()
35+
})
36+
2737
describe('defineProps w/ type declaration + withDefaults', () => {
2838
const res = withDefaults(
2939
defineProps<{

packages/runtime-core/src/apiSetupHelpers.ts

+15-15
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,7 @@ export function defineProps<
6161
PP extends ComponentObjectPropsOptions = ComponentObjectPropsOptions
6262
>(props: PP): Prettify<Readonly<ExtractPropTypes<PP>>>
6363
// overload 3: typed-based declaration
64-
export function defineProps<TypeProps>(): Prettify<
65-
Readonly<
66-
Omit<TypeProps, BooleanKey<TypeProps>> & {
67-
[K in keyof Pick<TypeProps, BooleanKey<TypeProps>>]-?: NotUndefined<
68-
TypeProps[K]
69-
>
70-
}
71-
>
72-
>
64+
export function defineProps<TypeProps>(): ResolveProps<TypeProps>
7365
// implementation
7466
export function defineProps() {
7567
if (__DEV__) {
@@ -78,6 +70,20 @@ export function defineProps() {
7870
return null as any
7971
}
8072

73+
type ResolveProps<T, BooleanKeys extends keyof T = BooleanKey<T>> = Prettify<
74+
Readonly<
75+
T & {
76+
[K in BooleanKeys]-?: boolean
77+
}
78+
>
79+
>
80+
81+
type BooleanKey<T, K extends keyof T = keyof T> = K extends any
82+
? [T[K]] extends [boolean | undefined]
83+
? K
84+
: never
85+
: never
86+
8187
/**
8288
* Vue `<script setup>` compiler macro for declaring a component's emitted
8389
* events. The expected argument is the same as the component `emits` option.
@@ -139,12 +145,6 @@ export function defineExpose<
139145

140146
type NotUndefined<T> = T extends undefined ? never : T
141147

142-
type BooleanKey<T, K extends keyof T = keyof T> = K extends any
143-
? [T[K]] extends [boolean | undefined]
144-
? K
145-
: never
146-
: never
147-
148148
type InferDefaults<T> = {
149149
[K in keyof T]?: InferDefault<T, NotUndefined<T[K]>>
150150
}

0 commit comments

Comments
 (0)