Skip to content

Commit

Permalink
fix(types): accept generic Component type in h()
Browse files Browse the repository at this point in the history
fix #922
  • Loading branch information
yyx990803 committed Apr 4, 2020
1 parent 5dcc645 commit c1d5928
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 24 deletions.
24 changes: 5 additions & 19 deletions packages/runtime-core/src/h.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
19 changes: 14 additions & 5 deletions test-dts/h.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
ref,
Fragment,
Teleport,
Suspense
Suspense,
Component
} from './index'

describe('h inference w/ element', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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({})
})

0 comments on commit c1d5928

Please sign in to comment.