From c1d5928f3b240a4a69bcd8d88494e4fe8d2e625b Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 4 Apr 2020 13:29:29 -0400 Subject: [PATCH] fix(types): accept generic Component type in h() fix #922 --- packages/runtime-core/src/h.ts | 24 +++++------------------- test-dts/h.test-d.ts | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/packages/runtime-core/src/h.ts b/packages/runtime-core/src/h.ts index 02e9bc8c..099fe380 100644 --- a/packages/runtime-core/src/h.ts +++ b/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

( type: FunctionalComponent

, 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( - type: ComponentOptionsWithObjectProps, - props?: - | (RawProps & ExtractPropTypes) - | ({} extends ExtractPropTypes ? null : never), - children?: RawChildren | RawSlots -): VNode // fake constructor type returned by `defineComponent` or class component export function h(type: Constructor, children?: RawChildren): VNode diff --git a/test-dts/h.test-d.ts b/test-dts/h.test-d.ts index e85bee45..338e1fc3 100644 --- a/test-dts/h.test-d.ts +++ b/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({}) +})