@@ -3,29 +3,19 @@ import {
3
3
type ComponentOptions ,
4
4
type ComponentPublicInstance ,
5
5
type PropType ,
6
- type Ref ,
7
6
type SetupContext ,
8
7
type Slots ,
9
8
type SlotsType ,
10
9
type VNode ,
11
10
createApp ,
12
11
defineComponent ,
13
12
h ,
14
- nextTick ,
15
13
reactive ,
16
14
ref ,
17
- render as vueRender ,
18
15
withKeys ,
19
16
withModifiers ,
20
17
} from 'vue'
21
18
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'
29
19
30
20
describe ( 'with object props' , ( ) => {
31
21
interface ExpectedProps {
@@ -2038,118 +2028,69 @@ expectString(instance.actionText)
2038
2028
// @ts -expect-error
2039
2029
expectString ( instance . $props . actionText )
2040
2030
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
+ )
2048
2042
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' } ] )
2053
2045
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
+ } )
2066
2054
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 /> )
2077
2057
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
+ )
2082
2062
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
+ )
2103
2068
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
+ }
2115
2074
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
+ ] )
2126
2080
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
+ } )
2128
2089
2129
- const App = defineComponent ( {
2130
- setup ( ) {
2131
- return ( ) => h ( Comp , { msg : 'Hello' , list : list . value } )
2132
- } ,
2133
- } )
2090
+ expectType < JSX . Element > ( < ExtendedGenericCompUser /> )
2134
2091
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
+ )
2155
2096
} )
0 commit comments