Ver Fonte

fix(types): accept generic Component type in h()

fix #922
Evan You há 6 anos atrás
pai
commit
c1d5928f3b
2 ficheiros alterados com 19 adições e 24 exclusões
  1. 5 19
      packages/runtime-core/src/h.ts
  2. 14 5
      test-dts/h.test-d.ts

+ 5 - 19
packages/runtime-core/src/h.ts

@@ -10,14 +10,8 @@ import { Teleport, TeleportProps } from './components/Teleport'
 import { Suspense, SuspenseProps } from './components/Suspense'
 import { isObject, isArray } from '@vue/shared'
 import { RawSlots } from './componentSlots'
-import { FunctionalComponent } from './component'
-import {
-  ComponentOptionsWithoutProps,
-  ComponentOptionsWithArrayProps,
-  ComponentOptionsWithObjectProps,
-  ComponentOptions
-} from './componentOptions'
-import { ExtractPropTypes } from './componentProps'
+import { FunctionalComponent, Component } from './component'
+import { ComponentOptions } from './componentOptions'
 
 // `h` is a more user-friendly version of `createVNode` that allows omitting the
 // props when possible. It is intended for manually written render functions.
@@ -108,27 +102,19 @@ export function h(
 ): VNode
 
 // functional component
-export function h(type: FunctionalComponent, children?: RawChildren): VNode
 export function h<P>(
   type: FunctionalComponent<P>,
   props?: (RawProps & P) | ({} extends P ? null : never),
   children?: RawChildren | RawSlots
 ): VNode
 
-// stateful component
-export function h(type: ComponentOptions, children?: RawChildren): VNode
+// catch-all for generic component types
+export function h(type: Component, children?: RawChildren): VNode
 export function h(
-  type: ComponentOptionsWithoutProps | ComponentOptionsWithArrayProps,
+  type: ComponentOptions | FunctionalComponent<{}>,
   props?: RawProps | null,
   children?: RawChildren | RawSlots
 ): VNode
-export function h<O>(
-  type: ComponentOptionsWithObjectProps<O>,
-  props?:
-    | (RawProps & ExtractPropTypes<O>)
-    | ({} extends ExtractPropTypes<O> ? null : never),
-  children?: RawChildren | RawSlots
-): VNode
 
 // fake constructor type returned by `defineComponent` or class component
 export function h(type: Constructor, children?: RawChildren): VNode

+ 14 - 5
test-dts/h.test-d.ts

@@ -6,7 +6,8 @@ import {
   ref,
   Fragment,
   Teleport,
-  Suspense
+  Suspense,
+  Component
 } from './index'
 
 describe('h inference w/ element', () => {
@@ -58,17 +59,15 @@ describe('h inference w/ functional component', () => {
   expectError(h(Func, { bar: 123 }))
 })
 
-describe('h inference w/ plain object component', () => {
+describe('h support w/ plain object component', () => {
   const Foo = {
     props: {
       foo: String
     }
   }
-
   h(Foo, { foo: 'ok' })
   h(Foo, { foo: 'ok', class: 'extra' })
-  // should fail on wrong type
-  expectError(h(Foo, { foo: 1 }))
+  // no inference in this case
 })
 
 describe('h inference w/ defineComponent', () => {
@@ -122,3 +121,13 @@ describe('h inference w/ defineComponent + direct function', () => {
   // should fail on wrong type
   expectError(h(Foo, { bar: 1, foo: 1 }))
 })
+
+// #922
+describe('h support for generic component type', () => {
+  function foo(bar: Component) {
+    h(bar)
+    h(bar, 'hello')
+    h(bar, { id: 'ok' }, 'hello')
+  }
+  foo({})
+})