fix(types): optional boolean props should have boolean type in return type of defineProps (#7619)

close #7116
fix #5847
fix #7487
This commit is contained in:
三咲智子 Kevin Deng 2023-02-02 10:57:28 +08:00 committed by GitHub
parent 30399d46b1
commit a0a010ddc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 2 deletions

View File

@ -58,7 +58,13 @@ export function defineProps<
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__) {
@ -128,6 +134,12 @@ export function defineExpose<
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]>>
}
@ -149,7 +161,6 @@ type PropsWithDefaults<Base, Defaults> = Base & {
: NotUndefined<Base[K]>
: never
}
/**
* Vue `<script setup>` compiler macro for providing props default values when
* using type-based `defineProps` declaration.

View File

@ -13,11 +13,16 @@ describe('defineProps w/ type 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', () => {
@ -31,6 +36,8 @@ describe('defineProps w/ type declaration + withDefaults', () => {
x?: string
y?: string
z?: string
bool?: boolean
boolAndUndefined: boolean | undefined
}>(),
{
number: 123,
@ -56,6 +63,9 @@ describe('defineProps w/ type declaration + withDefaults', () => {
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', () => {