Przeglądaj źródła

fix(types): avoid merging object union types when using withDefaults (#10596)

close #10594
Thimo Sietsma 2 lat temu
rodzic
commit
37ba93c213

+ 35 - 0
packages/dts-test/setupHelpers.test-d.ts

@@ -102,6 +102,41 @@ describe('defineProps w/ union type declaration + withDefaults', () => {
   )
 })
 
+describe('defineProps w/ object union + withDefaults', () => {
+  const props = withDefaults(
+    defineProps<
+      {
+        foo: string
+      } & (
+        | {
+            type: 'hello'
+            bar: string
+          }
+        | {
+            type: 'world'
+            bar: number
+          }
+      )
+    >(),
+    {
+      foo: 'default value!',
+    },
+  )
+
+  expectType<
+    | {
+        readonly type: 'hello'
+        readonly bar: string
+        readonly foo: string
+      }
+    | {
+        readonly type: 'world'
+        readonly bar: number
+        readonly foo: string
+      }
+  >(props)
+})
+
 describe('defineProps w/ generic type declaration + withDefaults', <T extends
   number, TA extends {
   a: string

+ 4 - 1
packages/runtime-core/src/apiSetupHelpers.ts

@@ -284,6 +284,9 @@ export function defineModel(): any {
 }
 
 type NotUndefined<T> = T extends undefined ? never : T
+type MappedOmit<T, K extends keyof any> = {
+  [P in keyof T as P extends K ? never : P]: T[P]
+}
 
 type InferDefaults<T> = {
   [K in keyof T]?: InferDefault<T, T[K]>
@@ -299,7 +302,7 @@ type PropsWithDefaults<
   T,
   Defaults extends InferDefaults<T>,
   BKeys extends keyof T,
-> = Readonly<Omit<T, keyof Defaults>> & {
+> = Readonly<MappedOmit<T, keyof Defaults>> & {
   readonly [K in keyof Defaults]-?: K extends keyof T
     ? Defaults[K] extends undefined
       ? T[K]