diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts
index e101a8c96a7..e00206baa00 100644
--- a/packages/runtime-core/src/componentOptions.ts
+++ b/packages/runtime-core/src/componentOptions.ts
@@ -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'
diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx
index 8dbf7ca29ff..ff04a0d6f3f 100644
--- a/test-dts/defineComponent.test-d.tsx
+++ b/test-dts/defineComponent.test-d.tsx
@@ -775,6 +775,41 @@ describe('extends with mixins', () => {
expectError()
// @ts-expect-error
expectError()
+
+ // #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(this.foo)
+ }
+ })
+ defineComponent({
+ mixins: [CompWithC, CompEmpty],
+ mounted() {
+ expectType(this.foo)
+ }
+ })
+ defineComponent({
+ mixins: [CompWithM, CompEmpty],
+ mounted() {
+ expectType<() => void>(this.foo)
+ }
+ })
})
describe('compatibility w/ createApp', () => {