Parcourir la source

fix(types/sfc): fix withDefaults type inference when using union types (#4925)

Cathrine Vaage il y a 4 ans
Parent
commit
04e5835196
2 fichiers modifiés avec 28 ajouts et 12 suppressions
  1. 13 12
      packages/runtime-core/src/apiSetupHelpers.ts
  2. 15 0
      test-dts/setupHelpers.test-d.ts

+ 13 - 12
packages/runtime-core/src/apiSetupHelpers.ts

@@ -127,20 +127,21 @@ export function defineExpose(exposed?: Record<string, any>) {
 type NotUndefined<T> = T extends undefined ? never : T
 
 type InferDefaults<T> = {
-  [K in keyof T]?: NotUndefined<T[K]> extends
-    | number
-    | string
-    | boolean
-    | symbol
-    | Function
-    ? NotUndefined<T[K]>
-    : (props: T) => NotUndefined<T[K]>
+  [K in keyof T]?: InferDefault<T, NotUndefined<T[K]>>
 }
 
-type PropsWithDefaults<Base, Defaults> = Base &
-  {
-    [K in keyof Defaults]: K extends keyof Base ? NotUndefined<Base[K]> : never
-  }
+type InferDefault<P, T> = T extends
+  | number
+  | string
+  | boolean
+  | symbol
+  | Function
+  ? T
+  : (props: P) => T
+
+type PropsWithDefaults<Base, Defaults> = Base & {
+  [K in keyof Defaults]: K extends keyof Base ? NotUndefined<Base[K]> : never
+}
 
 /**
  * Vue `<script setup>` compiler macro for providing props default values when

+ 15 - 0
test-dts/setupHelpers.test-d.ts

@@ -45,6 +45,21 @@ describe('defineProps w/ type declaration + withDefaults', () => {
   res.x.slice()
 })
 
+describe('defineProps w/ union type declaration + withDefaults', () => {
+  withDefaults(
+    defineProps<{
+      union1?: number | number[] | { x: number }
+      union2?: number | number[] | { x: number }
+      union3?: number | number[] | { x: number }
+    }>(),
+    {
+      union1: 123,
+      union2: () => [123],
+      union3: () => ({ x: 123 })
+    }
+  )
+})
+
 describe('defineProps w/ runtime declaration', () => {
   // runtime declaration
   const props = defineProps({