Bladeren bron

fix(types): retain union type narrowing with defaults applied (#12108)

close #12106
edison 1 jaar geleden
bovenliggende
commit
05685a9d7c
2 gewijzigde bestanden met toevoegingen van 34 en 15 verwijderingen
  1. 17 0
      packages-private/dts-test/setupHelpers.test-d.ts
  2. 17 15
      packages/runtime-core/src/apiSetupHelpers.ts

+ 17 - 0
packages-private/dts-test/setupHelpers.test-d.ts

@@ -240,6 +240,23 @@ describe('withDefaults w/ defineProp type is different from the defaults type',
   res1.value
 })
 
+describe('withDefaults w/ defineProp discriminate union type', () => {
+  const props = withDefaults(
+    defineProps<
+      { type: 'button'; buttonType?: 'submit' } | { type: 'link'; href: string }
+    >(),
+    {
+      type: 'button',
+    },
+  )
+  if (props.type === 'button') {
+    expectType<'submit' | undefined>(props.buttonType)
+  }
+  if (props.type === 'link') {
+    expectType<string>(props.href)
+  }
+})
+
 describe('defineProps w/ runtime declaration', () => {
   // runtime declaration
   const props = defineProps({

+ 17 - 15
packages/runtime-core/src/apiSetupHelpers.ts

@@ -331,21 +331,23 @@ type PropsWithDefaults<
   T,
   Defaults extends InferDefaults<T>,
   BKeys extends keyof T,
-> = Readonly<MappedOmit<T, keyof Defaults>> & {
-  readonly [K in keyof Defaults as K extends keyof T
-    ? K
-    : never]-?: K extends keyof T
-    ? Defaults[K] extends undefined
-      ? IfAny<Defaults[K], NotUndefined<T[K]>, T[K]>
-      : NotUndefined<T[K]>
-    : never
-} & {
-  readonly [K in BKeys]-?: K extends keyof Defaults
-    ? Defaults[K] extends undefined
-      ? boolean | undefined
-      : boolean
-    : boolean
-}
+> = T extends unknown
+  ? Readonly<MappedOmit<T, keyof Defaults>> & {
+      readonly [K in keyof Defaults as K extends keyof T
+        ? K
+        : never]-?: K extends keyof T
+        ? Defaults[K] extends undefined
+          ? IfAny<Defaults[K], NotUndefined<T[K]>, T[K]>
+          : NotUndefined<T[K]>
+        : never
+    } & {
+      readonly [K in BKeys]-?: K extends keyof Defaults
+        ? Defaults[K] extends undefined
+          ? boolean | undefined
+          : boolean
+        : boolean
+    }
+  : never
 
 /**
  * Vue `<script setup>` compiler macro for providing props default values when