]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(types): optional boolean props should have boolean type in return type of defineP...
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Thu, 2 Feb 2023 02:57:28 +0000 (10:57 +0800)
committerGitHub <noreply@github.com>
Thu, 2 Feb 2023 02:57:28 +0000 (21:57 -0500)
close #7116
fix #5847
fix #7487

packages/runtime-core/src/apiSetupHelpers.ts
test-dts/setupHelpers.test-d.ts

index 0ab3d252d553bf12e151356d69bef52de8db4946..6f6097aa80918fbb02aacc56638387b09072fb0e 100644 (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.
index e8066e4e5b783c9980ccd5bfdca684bb930b15c7..4d79fc8f479ab053db899e9f933f9387b941a004 100644 (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', () => {