Browse Source

feat: support functional components in defineComponent

close #12619
Evan You 3 years ago
parent
commit
559600f13d
2 changed files with 61 additions and 0 deletions
  1. 36 0
      types/test/v3/define-component-test.tsx
  2. 25 0
      types/v3-define-component.d.ts

+ 36 - 0
types/test/v3/define-component-test.tsx

@@ -1079,3 +1079,39 @@ export default {
     }
   })
 }
+
+describe('functional w/ array props', () => {
+  const Foo = defineComponent({
+    functional: true,
+    props: ['foo'],
+    render(h, ctx) {
+      ctx.props.foo
+      // @ts-expect-error
+      ctx.props.bar
+    }
+  })
+
+  ;<Foo foo="hi" />
+  // @ts-expect-error
+  ;<Foo bar={123} />
+})
+
+describe('functional w/ object props', () => {
+  const Foo = defineComponent({
+    functional: true,
+    props: {
+      foo: String
+    },
+    render(h, ctx) {
+      ctx.props.foo
+      // @ts-expect-error
+      ctx.props.bar
+    }
+  })
+
+  ;<Foo foo="hi" />
+  // @ts-expect-error
+  ;<Foo foo={123} />
+  // @ts-expect-error
+  ;<Foo bar={123} />
+})

+ 25 - 0
types/v3-define-component.d.ts

@@ -18,6 +18,7 @@ import {
 } from './v3-component-public-instance'
 import { Data, HasDefined } from './common'
 import { EmitsOptions } from './v3-setup-context'
+import { CreateElement, RenderContext } from './umd'
 
 type DefineComponent<
   PropsOrPropOptions = {},
@@ -66,6 +67,30 @@ type DefineComponent<
     props: PropsOrPropOptions
   }
 
+/**
+ * overload 0.0: functional component with array props
+ */
+export function defineComponent<
+  PropNames extends string,
+  Props = Readonly<{ [key in PropNames]?: any }>
+>(options: {
+  functional: true
+  props?: PropNames[]
+  render?: (h: CreateElement, context: RenderContext<Props>) => any
+}): DefineComponent<Props>
+
+/**
+ * overload 0.1: functional component with object props
+ */
+export function defineComponent<
+  PropsOptions extends ComponentPropsOptions = ComponentPropsOptions,
+  Props = ExtractPropTypes<PropsOptions>
+>(options: {
+  functional: true
+  props?: PropsOptions
+  render?: (h: CreateElement, context: RenderContext<Props>) => any
+}): DefineComponent<PropsOptions>
+
 /**
  * overload 1: object format with no props
  */