mirror of https://github.com/vuejs/core.git
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:
parent
30399d46b1
commit
a0a010ddc9
|
@ -58,7 +58,13 @@ export function defineProps<
|
||||||
PP extends ComponentObjectPropsOptions = ComponentObjectPropsOptions
|
PP extends ComponentObjectPropsOptions = ComponentObjectPropsOptions
|
||||||
>(props: PP): Readonly<ExtractPropTypes<PP>>
|
>(props: PP): Readonly<ExtractPropTypes<PP>>
|
||||||
// overload 3: typed-based declaration
|
// 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
|
// implementation
|
||||||
export function defineProps() {
|
export function defineProps() {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
|
@ -128,6 +134,12 @@ export function defineExpose<
|
||||||
|
|
||||||
type NotUndefined<T> = T extends undefined ? never : T
|
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> = {
|
type InferDefaults<T> = {
|
||||||
[K in keyof T]?: InferDefault<T, NotUndefined<T[K]>>
|
[K in keyof T]?: InferDefault<T, NotUndefined<T[K]>>
|
||||||
}
|
}
|
||||||
|
@ -149,7 +161,6 @@ type PropsWithDefaults<Base, Defaults> = Base & {
|
||||||
: NotUndefined<Base[K]>
|
: NotUndefined<Base[K]>
|
||||||
: never
|
: never
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vue `<script setup>` compiler macro for providing props default values when
|
* Vue `<script setup>` compiler macro for providing props default values when
|
||||||
* using type-based `defineProps` declaration.
|
* using type-based `defineProps` declaration.
|
||||||
|
|
|
@ -13,11 +13,16 @@ describe('defineProps w/ type declaration', () => {
|
||||||
// type declaration
|
// type declaration
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
foo: string
|
foo: string
|
||||||
|
bool?: boolean
|
||||||
|
boolAndUndefined: boolean | undefined
|
||||||
}>()
|
}>()
|
||||||
// explicitly declared type should be refined
|
// explicitly declared type should be refined
|
||||||
expectType<string>(props.foo)
|
expectType<string>(props.foo)
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
props.bar
|
props.bar
|
||||||
|
|
||||||
|
expectType<boolean>(props.bool)
|
||||||
|
expectType<boolean>(props.boolAndUndefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('defineProps w/ type declaration + withDefaults', () => {
|
describe('defineProps w/ type declaration + withDefaults', () => {
|
||||||
|
@ -31,6 +36,8 @@ describe('defineProps w/ type declaration + withDefaults', () => {
|
||||||
x?: string
|
x?: string
|
||||||
y?: string
|
y?: string
|
||||||
z?: string
|
z?: string
|
||||||
|
bool?: boolean
|
||||||
|
boolAndUndefined: boolean | undefined
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
number: 123,
|
number: 123,
|
||||||
|
@ -56,6 +63,9 @@ describe('defineProps w/ type declaration + withDefaults', () => {
|
||||||
expectType<string | undefined>(res.x)
|
expectType<string | undefined>(res.x)
|
||||||
expectType<string | undefined>(res.y)
|
expectType<string | undefined>(res.y)
|
||||||
expectType<string>(res.z)
|
expectType<string>(res.z)
|
||||||
|
|
||||||
|
expectType<boolean>(res.bool)
|
||||||
|
expectType<boolean>(res.boolAndUndefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('defineProps w/ union type declaration + withDefaults', () => {
|
describe('defineProps w/ union type declaration + withDefaults', () => {
|
||||||
|
|
Loading…
Reference in New Issue