Procházet zdrojové kódy

fix(types): make generics with runtime props in defineVaporComponent work (#14770)

zhiyuanzmj před 1 měsícem
rodič
revize
8c99b9ab65

+ 88 - 11
packages-private/dts-test/vapor/defineVaporComponent.test-d.tsx

@@ -820,7 +820,7 @@ describe('function syntax w/ expose', () => {
 describe('function syntax w/ runtime props', () => {
   // with runtime props, the runtime props must match
   // manual type declaration
-  defineVaporComponent(
+  const Comp1 = defineVaporComponent(
     (_props: { msg: string }) => {
       return []
     },
@@ -829,7 +829,34 @@ describe('function syntax w/ runtime props', () => {
     },
   )
 
+  // @ts-expect-error bar isn't specified in props definition
   defineVaporComponent(
+    (_props: { msg: string }) => {
+      return []
+    },
+    {
+      props: ['msg', 'bar'],
+    },
+  )
+
+  defineVaporComponent(
+    (_props: { msg: string; bar: string }) => {
+      return []
+    },
+    {
+      props: ['msg'],
+    },
+  )
+
+  expectType<JSX.Element>(<Comp1 msg="1" />)
+  // @ts-expect-error msg type is incorrect
+  expectType<JSX.Element>(<Comp1 msg={1} />)
+  // @ts-expect-error msg is missing
+  expectType<JSX.Element>(<Comp1 />)
+  // @ts-expect-error bar doesn't exist
+  expectType<JSX.Element>(<Comp1 msg="1" bar="2" />)
+
+  const Comp2 = defineVaporComponent(
     <T extends string>(_props: { msg: T }) => {
       return []
     },
@@ -838,7 +865,36 @@ describe('function syntax w/ runtime props', () => {
     },
   )
 
+  // @ts-expect-error bar isn't specified in props definition
   defineVaporComponent(
+    <T extends string>(_props: { msg: T }) => {
+      return []
+    },
+    {
+      props: ['msg', 'bar'],
+    },
+  )
+
+  defineVaporComponent(
+    <T extends string>(_props: { msg: T; bar: T }) => {
+      return []
+    },
+    {
+      props: ['msg'],
+    },
+  )
+
+  expectType<JSX.Element>(<Comp2 msg="1" />)
+  expectType<JSX.Element>(<Comp2<string> msg="1" />)
+  // @ts-expect-error msg type is incorrect
+  expectType<JSX.Element>(<Comp2 msg={1} />)
+  // @ts-expect-error msg is missing
+  expectType<JSX.Element>(<Comp2 />)
+  // @ts-expect-error bar doesn't exist
+  expectType<JSX.Element>(<Comp2 msg="1" bar="2" />)
+
+  // Note: generics aren't supported with object runtime props
+  const Comp3 = defineVaporComponent(
     <T extends string>(_props: { msg: T }) => {
       return []
     },
@@ -849,37 +905,58 @@ describe('function syntax w/ runtime props', () => {
     },
   )
 
-  // @ts-expect-error string prop names don't match
   defineVaporComponent(
-    (_props: { msg: string }) => {
+    // @ts-expect-error bar isn't specified in props definition
+    <T extends string>(_props: { msg: T }) => {
       return []
     },
     {
-      props: ['bar'],
+      props: {
+        bar: String,
+      },
     },
   )
 
   defineVaporComponent(
-    (_props: { msg: string }) => {
+    // @ts-expect-error generics aren't supported with object runtime props
+    <T extends string>(_props: { msg: T; bar: T }) => {
       return []
     },
     {
       props: {
-        // @ts-expect-error prop type mismatch
-        msg: Number,
+        msg: String,
       },
     },
   )
 
-  // @ts-expect-error prop keys don't match
+  expectType<JSX.Element>(<Comp3 msg="1" />)
+  // @ts-expect-error generics aren't supported with object runtime props
+  expectType<JSX.Element>(<Comp3<string> msg="1" />)
+  // @ts-expect-error msg type is incorrect
+  expectType<JSX.Element>(<Comp3 msg={1} />)
+  // @ts-expect-error msg is missing
+  expectType<JSX.Element>(<Comp3 />)
+  // @ts-expect-error bar doesn't exist
+  expectType<JSX.Element>(<Comp3 msg="1" bar="2" />)
+
+  // @ts-expect-error string prop names don't match
   defineVaporComponent(
-    (_props: { msg: string }, ctx) => {
+    (_props: { msg: string }) => {
+      return []
+    },
+    {
+      props: ['bar'],
+    },
+  )
+
+  defineVaporComponent(
+    (_props: { msg: string }) => {
       return []
     },
     {
       props: {
-        msg: String,
-        bar: String,
+        // @ts-expect-error prop type mismatch
+        msg: Number,
       },
     },
   )

+ 1 - 1
packages/runtime-vapor/src/apiDefineComponent.ts

@@ -113,7 +113,7 @@ export function defineVaporComponent<
     },
   ) => VaporRenderResult<TypeBlock> | void,
   extraOptions?: VaporComponentOptions<
-    (keyof Props)[],
+    (keyof NoInfer<Props>)[],
     Emits,
     RuntimeEmitsKeys,
     Slots,

+ 1 - 1
packages/runtime-vapor/src/apiDefineCustomElement.ts

@@ -58,7 +58,7 @@ export function defineVaporCustomElement<Props, RawBindings = object>(
   ) => RawBindings | VaporRenderResult,
   options?: Pick<VaporComponentOptions, 'name' | 'inheritAttrs' | 'emits'> &
     CustomElementOptions & {
-      props?: (keyof Props)[]
+      props?: (keyof NoInfer<Props>)[]
     },
 ): VaporElementConstructor<Props>
 export function defineVaporCustomElement<Props, RawBindings = object>(