Skip to content

Commit e46dfdd

Browse files
committed
fix: change test for component
1 parent afeda80 commit e46dfdd

File tree

2 files changed

+56
-117
lines changed

2 files changed

+56
-117
lines changed

packages-private/dts-test/defineComponent.test-d.tsx

+55-114
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,19 @@ import {
33
type ComponentOptions,
44
type ComponentPublicInstance,
55
type PropType,
6-
type Ref,
76
type SetupContext,
87
type Slots,
98
type SlotsType,
109
type VNode,
1110
createApp,
1211
defineComponent,
1312
h,
14-
nextTick,
1513
reactive,
1614
ref,
17-
render as vueRender,
1815
withKeys,
1916
withModifiers,
2017
} from 'vue'
2118
import { type IsAny, type IsUnion, describe, expectType } from './utils'
22-
import {
23-
type TestElement,
24-
type TestNode,
25-
nodeOps,
26-
serializeInner,
27-
triggerEvent,
28-
} from '@vue/runtime-test'
2919

3020
describe('with object props', () => {
3121
interface ExpectedProps {
@@ -2038,118 +2028,69 @@ expectString(instance.actionText)
20382028
// @ts-expect-error
20392029
expectString(instance.$props.actionText)
20402030

2041-
// Helper function to safely cast TestNode to TestElement
2042-
function getFirstElementChild(node: TestNode): TestElement {
2043-
if ('children' in node) {
2044-
return node.children[0] as TestElement
2045-
}
2046-
throw new Error('Expected an element with children')
2047-
}
2031+
describe('generic components in defineComponent', () => {
2032+
const GenericComp = defineComponent(
2033+
<T extends { name: string }>(props: { msg: string; list: T[] }) => {
2034+
return () => (
2035+
<div>
2036+
{props.msg}
2037+
{props.list.map(item => item.name).join(', ')}
2038+
</div>
2039+
)
2040+
},
2041+
)
20482042

2049-
// Custom render function with correct typing for TestElement
2050-
function render(vnode: any, root: TestElement) {
2051-
return vueRender(vnode, root as any)
2052-
}
2043+
const GenericCompUser = defineComponent(() => {
2044+
const list = ref([{ name: 'Tom' }, { name: 'Jack' }])
20532045

2054-
describe('defineComponent with generics', () => {
2055-
test('defineComponent with generic', async () => {
2056-
const Comp = defineComponent({
2057-
props: {
2058-
msg: String,
2059-
list: Array as PropType<{ name: string }[]>,
2060-
},
2061-
setup(props) {
2062-
const count = ref(0)
2063-
const increment = () => {
2064-
count.value++
2065-
}
2046+
return () => {
2047+
return (
2048+
<div>
2049+
<GenericComp<{ name: string }> msg="hello" list={list.value} />
2050+
</div>
2051+
)
2052+
}
2053+
})
20662054

2067-
return () =>
2068-
h('div', { onClick: increment }, [
2069-
h('h2', props.msg),
2070-
h('p', count.value),
2071-
...(props.list || []).map((item: { name: string }) =>
2072-
h('p', item.name),
2073-
),
2074-
])
2075-
},
2076-
})
2055+
// Test correct usage
2056+
expectType<JSX.Element>(<GenericCompUser />)
20772057

2078-
const list: Ref<{ name: string }[]> = ref([
2079-
{ name: 'Tom' },
2080-
{ name: 'Jerry' },
2081-
])
2058+
// Test GenericComp directly with correct props
2059+
expectType<JSX.Element>(
2060+
<GenericComp<{ name: string }> msg="hello" list={[{ name: 'Alice' }]} />,
2061+
)
20822062

2083-
const root = nodeOps.createElement('div')
2084-
render(h(Comp, { msg: 'Hello', list: list.value }), root)
2085-
2086-
expect(serializeInner(root)).toBe(
2087-
`<div><h2>Hello</h2><p>0</p><p>Tom</p><p>Jerry</p></div>`,
2088-
)
2089-
2090-
const firstChild = getFirstElementChild(root)
2091-
triggerEvent(firstChild, 'click')
2092-
await nextTick()
2093-
expect(serializeInner(root)).toBe(
2094-
`<div><h2>Hello</h2><p>1</p><p>Tom</p><p>Jerry</p></div>`,
2095-
)
2096-
2097-
list.value.push({ name: 'Spike' })
2098-
await nextTick()
2099-
expect(serializeInner(root)).toBe(
2100-
`<div><h2>Hello</h2><p>1</p><p>Tom</p><p>Jerry</p><p>Spike</p></div>`,
2101-
)
2102-
})
2063+
// Test with missing required prop
2064+
expectType<JSX.Element>(
2065+
// @ts-expect-error
2066+
<GenericComp<{ name: string }> list={[{ name: 'Bob' }]} />,
2067+
)
21032068

2104-
test('defineComponent with generic in render function', async () => {
2105-
const Comp = defineComponent({
2106-
props: {
2107-
msg: String,
2108-
list: Array as PropType<{ name: string }[]>,
2109-
},
2110-
setup(props) {
2111-
const count = ref(0)
2112-
const increment = () => {
2113-
count.value++
2114-
}
2069+
// Test with extended type
2070+
interface Person {
2071+
name: string
2072+
age: number
2073+
}
21152074

2116-
return () =>
2117-
h('div', { onClick: increment }, [
2118-
h('h2', props.msg),
2119-
h('p', count.value),
2120-
...(props.list || []).map((item: { name: string }) =>
2121-
h('p', item.name),
2122-
),
2123-
])
2124-
},
2125-
})
2075+
const ExtendedGenericCompUser = defineComponent(() => {
2076+
const people = ref<Person[]>([
2077+
{ name: 'Tom', age: 25 },
2078+
{ name: 'Jack', age: 30 },
2079+
])
21262080

2127-
const list = ref([{ name: 'Tom' }, { name: 'Jerry' }])
2081+
return () => {
2082+
return (
2083+
<div>
2084+
<GenericComp<Person> msg="people" list={people.value} />
2085+
</div>
2086+
)
2087+
}
2088+
})
21282089

2129-
const App = defineComponent({
2130-
setup() {
2131-
return () => h(Comp, { msg: 'Hello', list: list.value })
2132-
},
2133-
})
2090+
expectType<JSX.Element>(<ExtendedGenericCompUser />)
21342091

2135-
const root = nodeOps.createElement('div')
2136-
render(h(App), root)
2137-
2138-
expect(serializeInner(root)).toBe(
2139-
`<div><h2>Hello</h2><p>0</p><p>Tom</p><p>Jerry</p></div>`,
2140-
)
2141-
2142-
const firstChild = getFirstElementChild(root)
2143-
triggerEvent(firstChild, 'click')
2144-
await nextTick()
2145-
expect(serializeInner(root)).toBe(
2146-
`<div><h2>Hello</h2><p>1</p><p>Tom</p><p>Jerry</p></div>`,
2147-
)
2148-
2149-
list.value.push({ name: 'Spike' })
2150-
await nextTick()
2151-
expect(serializeInner(root)).toBe(
2152-
`<div><h2>Hello</h2><p>1</p><p>Tom</p><p>Jerry</p><p>Spike</p></div>`,
2153-
)
2154-
})
2092+
// Test GenericComp directly with extended type
2093+
expectType<JSX.Element>(
2094+
<GenericComp<Person> msg="people" list={[{ name: 'Alice', age: 28 }]} />,
2095+
)
21552096
})

packages/runtime-core/src/apiDefineComponent.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,7 @@ export type DefineComponentWithGeneric<
184184
S
185185
> &
186186
PP & {
187-
<T extends Record<string, any> = Generic>(
188-
props: Props & { ref?: Ref<any> },
189-
): VNode
187+
<T extends Generic>(props: Props & { ref?: Ref<any> } & T): VNode
190188
}
191189

192190
// defineComponent is a utility that is primarily used for type inference

0 commit comments

Comments
 (0)