]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(types): avoid merging component instance into `$props` in `ComponentInstance...
authorTycho <jh.leong@outlook.com>
Tue, 20 May 2025 00:44:35 +0000 (08:44 +0800)
committerGitHub <noreply@github.com>
Tue, 20 May 2025 00:44:35 +0000 (08:44 +0800)
close #12751

packages-private/dts-test/componentInstance.test-d.tsx
packages/runtime-core/src/component.ts

index a804bb10d5ddbab655bf9dc1398a9a647e3d748c..c6911d3a8cab13e0630b5d030a3b712ce347b35c 100644 (file)
@@ -137,3 +137,18 @@ describe('Generic component', () => {
   expectType<string | number>(comp.msg)
   expectType<Array<string | number>>(comp.list)
 })
+
+// #12751
+{
+  const Comp = defineComponent({
+    __typeEmits: {} as {
+      'update:visible': [value?: boolean]
+    },
+  })
+  const comp: ComponentInstance<typeof Comp> = {} as any
+
+  expectType<((value?: boolean) => any) | undefined>(comp['onUpdate:visible'])
+  expectType<{ 'onUpdate:visible'?: (value?: boolean) => any }>(comp['$props'])
+  // @ts-expect-error
+  comp['$props']['$props']
+}
index 5b094a0d611dfcea00615cbceed901f1b2efa7c5..f191c36df1242e8cc505471ed125f73f4172d94c 100644 (file)
@@ -115,20 +115,23 @@ export type ComponentInstance<T> = T extends { new (): ComponentPublicInstance }
   : T extends FunctionalComponent<infer Props, infer Emits>
     ? ComponentPublicInstance<Props, {}, {}, {}, {}, ShortEmitsToObject<Emits>>
     : T extends Component<
-          infer Props,
+          infer PropsOrInstance,
           infer RawBindings,
           infer D,
           infer C,
           infer M
         >
-      ? // NOTE we override Props/RawBindings/D to make sure is not `unknown`
-        ComponentPublicInstance<
-          unknown extends Props ? {} : Props,
-          unknown extends RawBindings ? {} : RawBindings,
-          unknown extends D ? {} : D,
-          C,
-          M
-        >
+      ? PropsOrInstance extends { $props: unknown }
+        ? // T is returned by `defineComponent()`
+          PropsOrInstance
+        : // NOTE we override Props/RawBindings/D to make sure is not `unknown`
+          ComponentPublicInstance<
+            unknown extends PropsOrInstance ? {} : PropsOrInstance,
+            unknown extends RawBindings ? {} : RawBindings,
+            unknown extends D ? {} : D,
+            C,
+            M
+          >
       : never // not a vue Component
 
 /**
@@ -259,7 +262,7 @@ export type ConcreteComponent<
  * The constructor type is an artificial type returned by defineComponent().
  */
 export type Component<
-  Props = any,
+  PropsOrInstance = any,
   RawBindings = any,
   D = any,
   C extends ComputedOptions = ComputedOptions,
@@ -267,8 +270,8 @@ export type Component<
   E extends EmitsOptions | Record<string, any[]> = {},
   S extends Record<string, any> = any,
 > =
-  | ConcreteComponent<Props, RawBindings, D, C, M, E, S>
-  | ComponentPublicInstanceConstructor<Props>
+  | ConcreteComponent<PropsOrInstance, RawBindings, D, C, M, E, S>
+  | ComponentPublicInstanceConstructor<PropsOrInstance>
 
 export type { ComponentOptions }