]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(types): accept generic Component type in h()
authorEvan You <yyx990803@gmail.com>
Sat, 4 Apr 2020 17:29:29 +0000 (13:29 -0400)
committerEvan You <yyx990803@gmail.com>
Sat, 4 Apr 2020 17:29:29 +0000 (13:29 -0400)
fix #922

packages/runtime-core/src/h.ts
test-dts/h.test-d.ts

index 02e9bc8ce8a862e8ef08269b63d2f3e248fcfbb2..099fe38057d1598a183789014464c84b594993e5 100644 (file)
@@ -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
index e85bee45bcafae22039bba84abf1495f73b3a70c..338e1fc36f3d3de484c32e96ba66a5872cea0916 100644 (file)
@@ -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({})
+})