PP extends ComponentObjectPropsOptions = ComponentObjectPropsOptions
>(props: PP): Readonly<ExtractPropTypes<PP>>
// overload 3: typed-based declaration
-export function defineProps<TypeProps>(): Readonly<TypeProps>
+export function defineProps<TypeProps>(): Readonly<
+ Omit<TypeProps, BooleanKey<TypeProps>> & {
+ [K in keyof Pick<TypeProps, BooleanKey<TypeProps>>]-?: NotUndefined<
+ TypeProps[K]
+ >
+ }
+>
// implementation
export function defineProps() {
if (__DEV__) {
type NotUndefined<T> = T extends undefined ? never : T
+type BooleanKey<T, K extends keyof T = keyof T> = K extends any
+ ? [T[K]] extends [boolean | undefined]
+ ? K
+ : never
+ : never
+
type InferDefaults<T> = {
[K in keyof T]?: InferDefault<T, NotUndefined<T[K]>>
}
: NotUndefined<Base[K]>
: never
}
-
/**
* Vue `<script setup>` compiler macro for providing props default values when
* using type-based `defineProps` declaration.
// type declaration
const props = defineProps<{
foo: string
+ bool?: boolean
+ boolAndUndefined: boolean | undefined
}>()
// explicitly declared type should be refined
expectType<string>(props.foo)
// @ts-expect-error
props.bar
+
+ expectType<boolean>(props.bool)
+ expectType<boolean>(props.boolAndUndefined)
})
describe('defineProps w/ type declaration + withDefaults', () => {
x?: string
y?: string
z?: string
+ bool?: boolean
+ boolAndUndefined: boolean | undefined
}>(),
{
number: 123,
expectType<string | undefined>(res.x)
expectType<string | undefined>(res.y)
expectType<string>(res.z)
+
+ expectType<boolean>(res.bool)
+ expectType<boolean>(res.boolAndUndefined)
})
describe('defineProps w/ union type declaration + withDefaults', () => {