]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(types): add a type-only differentiator to assist Mixin's type infer (#3481)
authorHcySunYang <HcySunYang@outlook.com>
Mon, 29 Mar 2021 22:07:36 +0000 (06:07 +0800)
committerGitHub <noreply@github.com>
Mon, 29 Mar 2021 22:07:36 +0000 (18:07 -0400)
fix #3468

packages/runtime-core/src/componentOptions.ts
test-dts/defineComponent.test-d.tsx

index e101a8c96a7aef128a676a0ad69e84141bf69453..e00206baa003f7d230b029fd071bf1abf1c801b7 100644 (file)
@@ -424,6 +424,16 @@ interface LegacyOptions<
 
   // runtime compile only
   delimiters?: [string, string]
+
+  /**
+   * #3468
+   *
+   * type-only, used to assist Mixin's type inference,
+   * typescript will try to simplify the inferred `Mixin` type,
+   * with the `__differenciator`, typescript won't be able to combine different mixins,
+   * because the `__differenciator` will be different
+   */
+  __differentiator?: keyof D | keyof C | keyof M
 }
 
 export type OptionTypesKeys = 'P' | 'B' | 'D' | 'C' | 'M' | 'Defaults'
index 8dbf7ca29ffcd296819020aff5e0ada0618150ba..ff04a0d6f3fd2c547fa79d5830b951f1b04ef2eb 100644 (file)
@@ -775,6 +775,41 @@ describe('extends with mixins', () => {
   expectError(<MyComponent p2={'wrong type'} z={'z'} />)
   // @ts-expect-error
   expectError(<MyComponent mP1={3} />)
+
+  // #3468
+  const CompWithD = defineComponent({
+    data() {
+      return { foo: 1 }
+    }
+  })
+  const CompWithC = defineComponent({
+    computed: {
+      foo() {
+        return 1
+      }
+    }
+  })
+  const CompWithM = defineComponent({ methods: { foo() {} } })
+  const CompEmpty = defineComponent({})
+
+  defineComponent({
+    mixins: [CompWithD, CompEmpty],
+    mounted() {
+      expectType<number>(this.foo)
+    }
+  })
+  defineComponent({
+    mixins: [CompWithC, CompEmpty],
+    mounted() {
+      expectType<number>(this.foo)
+    }
+  })
+  defineComponent({
+    mixins: [CompWithM, CompEmpty],
+    mounted() {
+      expectType<() => void>(this.foo)
+    }
+  })
 })
 
 describe('compatibility w/ createApp', () => {