Skip to content

Commit 43065b5

Browse files
committed
types(defineProps): remove optional properties from type
1 parent a95554d commit 43065b5

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

packages/runtime-core/src/apiSetupHelpers.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,14 @@ 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<T>(): T extends object
62+
? {
63+
// use needed to remove the optional property
64+
[K in keyof Required<T>]: K extends OptionalPropertyOf<T>
65+
? T[K] | undefined
66+
: T[K]
67+
}
68+
: Readonly<T>
6269
// implementation
6370
export function defineProps() {
6471
if (__DEV__) {

packages/shared/src/typeUtils.ts

+9
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,12 @@ export type LooseRequired<T> = { [P in string & keyof T]: T[P] }
1010
// If the the type T accepts type "any", output type Y, otherwise output type N.
1111
// https://stackoverflow.com/questions/49927523/disallow-call-with-any/49928360#49928360
1212
export type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N
13+
14+
// Extract optional properties from a type
15+
// https://stackoverflow.com/a/53899815
16+
export type OptionalPropertyOf<T extends object> = Exclude<
17+
{
18+
[K in keyof T]: T extends Record<K, T[K]> ? never : K
19+
}[keyof T],
20+
undefined
21+
>

test-dts/setupHelpers.test-d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ describe('defineProps w/ type declaration', () => {
1313
// type declaration
1414
const props = defineProps<{
1515
foo: string
16+
x?: string
1617
}>()
1718
// explicitly declared type should be refined
1819
expectType<string>(props.foo)
20+
21+
// force check the actual type doing expectType<string|undefined>(props.x) does not
22+
// error when is not undefined, this way it does
23+
// #6420
24+
expectType<typeof props['x']>({} as unknown as string | undefined)
1925
// @ts-expect-error
2026
props.bar
2127
})

0 commit comments

Comments
 (0)