h.test-d.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import {
  2. h,
  3. defineComponent,
  4. DefineComponent,
  5. ref,
  6. Fragment,
  7. Teleport,
  8. Suspense,
  9. Component,
  10. resolveComponent
  11. } from 'vue'
  12. import { describe, expectAssignable } from './utils'
  13. describe('h inference w/ element', () => {
  14. // key
  15. h('div', { key: 1 })
  16. h('div', { key: 'foo' })
  17. // @ts-expect-error
  18. h('div', { key: [] })
  19. // @ts-expect-error
  20. h('div', { key: {} })
  21. // ref
  22. h('div', { ref: 'foo' })
  23. h('div', { ref: ref(null) })
  24. h('div', { ref: _el => {} })
  25. // @ts-expect-error
  26. h('div', { ref: [] })
  27. // @ts-expect-error
  28. h('div', { ref: {} })
  29. // @ts-expect-error
  30. h('div', { ref: 123 })
  31. // slots
  32. const slots = { default: () => {} } // RawSlots
  33. h('div', {}, slots)
  34. })
  35. describe('h inference w/ Fragment', () => {
  36. // only accepts array children
  37. h(Fragment, ['hello'])
  38. h(Fragment, { key: 123 }, ['hello'])
  39. // @ts-expect-error
  40. h(Fragment, 'foo')
  41. // @ts-expect-error
  42. h(Fragment, { key: 123 }, 'bar')
  43. })
  44. describe('h inference w/ Teleport', () => {
  45. h(Teleport, { to: '#foo' }, 'hello')
  46. h(Teleport, { to: '#foo' }, { default() {} })
  47. // @ts-expect-error
  48. h(Teleport)
  49. // @ts-expect-error
  50. h(Teleport, {})
  51. // @ts-expect-error
  52. h(Teleport, { to: '#foo' })
  53. })
  54. describe('h inference w/ Suspense', () => {
  55. h(Suspense, { onRecede: () => {}, onResolve: () => {} }, 'hello')
  56. h(Suspense, 'foo')
  57. h(Suspense, () => 'foo')
  58. h(Suspense, null, {
  59. default: () => 'foo'
  60. })
  61. // @ts-expect-error
  62. h(Suspense, { onResolve: 1 })
  63. })
  64. describe('h inference w/ functional component', () => {
  65. const Func = (_props: { foo: string; bar?: number }) => ''
  66. h(Func, { foo: 'hello' })
  67. h(Func, { foo: 'hello', bar: 123 })
  68. // @ts-expect-error
  69. h(Func, { foo: 123 })
  70. // @ts-expect-error
  71. h(Func, {})
  72. // @ts-expect-error
  73. h(Func, { bar: 123 })
  74. })
  75. describe('h support w/ plain object component', () => {
  76. const Foo = {
  77. props: {
  78. foo: String
  79. }
  80. }
  81. h(Foo, { foo: 'ok' })
  82. h(Foo, { foo: 'ok', class: 'extra' })
  83. // no inference in this case
  84. })
  85. describe('h inference w/ defineComponent', () => {
  86. const Foo = defineComponent({
  87. props: {
  88. foo: String,
  89. bar: {
  90. type: Number,
  91. required: true
  92. }
  93. }
  94. })
  95. h(Foo, { bar: 1 })
  96. h(Foo, { bar: 1, foo: 'ok' })
  97. // should allow extraneous props (attrs fallthrough)
  98. h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
  99. // @ts-expect-error should fail on missing required prop
  100. h(Foo, {})
  101. // @ts-expect-error
  102. h(Foo, { foo: 'ok' })
  103. // @ts-expect-error should fail on wrong type
  104. h(Foo, { bar: 1, foo: 1 })
  105. })
  106. // describe('h inference w/ defineComponent + optional props', () => {
  107. // const Foo = defineComponent({
  108. // setup(_props: { foo?: string; bar: number }) {}
  109. // })
  110. // h(Foo, { bar: 1 })
  111. // h(Foo, { bar: 1, foo: 'ok' })
  112. // // should allow extraneous props (attrs fallthrough)
  113. // h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
  114. // // @ts-expect-error should fail on missing required prop
  115. // h(Foo, {})
  116. // // @ts-expect-error
  117. // h(Foo, { foo: 'ok' })
  118. // // @ts-expect-error should fail on wrong type
  119. // h(Foo, { bar: 1, foo: 1 })
  120. // })
  121. // describe('h inference w/ defineComponent + direct function', () => {
  122. // const Foo = defineComponent((_props: { foo?: string; bar: number }) => {})
  123. // h(Foo, { bar: 1 })
  124. // h(Foo, { bar: 1, foo: 'ok' })
  125. // // should allow extraneous props (attrs fallthrough)
  126. // h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
  127. // // @ts-expect-error should fail on missing required prop
  128. // h(Foo, {})
  129. // // @ts-expect-error
  130. // h(Foo, { foo: 'ok' })
  131. // // @ts-expect-error should fail on wrong type
  132. // h(Foo, { bar: 1, foo: 1 })
  133. // })
  134. // #922 and #3218
  135. describe('h support for generic component type', () => {
  136. function foo(bar: Component) {
  137. h(bar)
  138. h(bar, 'hello')
  139. h(bar, { id: 'ok' }, 'hello')
  140. }
  141. foo({})
  142. })
  143. // #993
  144. describe('describeComponent extends Component', () => {
  145. // functional
  146. expectAssignable<Component>(
  147. defineComponent((_props: { foo?: string; bar: number }) => () => {})
  148. )
  149. // typed props
  150. expectAssignable<Component>(defineComponent({}))
  151. // prop arrays
  152. expectAssignable<Component>(
  153. defineComponent({
  154. props: ['a', 'b']
  155. })
  156. )
  157. // prop object
  158. expectAssignable<Component>(
  159. defineComponent({
  160. props: {
  161. foo: String,
  162. bar: {
  163. type: Number,
  164. required: true
  165. }
  166. }
  167. })
  168. )
  169. })
  170. // #1385
  171. describe('component w/ props w/ default value', () => {
  172. const MyComponent = defineComponent({
  173. props: {
  174. message: {
  175. type: String,
  176. default: 'hello'
  177. }
  178. }
  179. })
  180. h(MyComponent, {})
  181. })
  182. // #2338
  183. describe('Boolean prop implicit false', () => {
  184. const MyComponent = defineComponent({
  185. props: {
  186. visible: Boolean
  187. }
  188. })
  189. h(MyComponent, {})
  190. const RequiredComponent = defineComponent({
  191. props: {
  192. visible: {
  193. type: Boolean,
  194. required: true
  195. }
  196. }
  197. })
  198. h(RequiredComponent, {
  199. visible: true
  200. })
  201. // @ts-expect-error
  202. h(RequiredComponent, {})
  203. })
  204. // #2357
  205. describe('resolveComponent should work', () => {
  206. h(resolveComponent('test'))
  207. h(resolveComponent('test'), {
  208. message: '1'
  209. })
  210. })
  211. // #5431
  212. describe('h should work with multiple types', () => {
  213. const serializers = {
  214. Paragraph: 'p',
  215. Component: {} as Component,
  216. DefineComponent: {} as DefineComponent
  217. }
  218. const sampleComponent = serializers['' as keyof typeof serializers]
  219. h(sampleComponent)
  220. h(sampleComponent, {})
  221. h(sampleComponent, {}, [])
  222. })