watch.test-d.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import {
  2. computed,
  3. defineComponent,
  4. defineModel,
  5. ref,
  6. shallowRef,
  7. watch,
  8. } from 'vue'
  9. import { expectType } from './utils'
  10. const source = ref('foo')
  11. const source2 = computed(() => source.value)
  12. const source3 = () => 1
  13. type OnCleanup = (fn: () => void) => void
  14. // lazy watcher will have consistent types for oldValue.
  15. watch(source, (value, oldValue, onCleanup) => {
  16. expectType<string>(value)
  17. expectType<string>(oldValue)
  18. expectType<OnCleanup>(onCleanup)
  19. })
  20. watch([source, source2, source3], (values, oldValues) => {
  21. expectType<[string, string, number]>(values)
  22. expectType<[string, string, number]>(oldValues)
  23. })
  24. // const array
  25. watch([source, source2, source3] as const, (values, oldValues) => {
  26. expectType<Readonly<[string, string, number]>>(values)
  27. expectType<Readonly<[string, string, number]>>(oldValues)
  28. })
  29. // immediate watcher's oldValue will be undefined on first run.
  30. watch(
  31. source,
  32. (value, oldValue) => {
  33. expectType<string>(value)
  34. expectType<string | undefined>(oldValue)
  35. },
  36. { immediate: true },
  37. )
  38. watch(
  39. [source, source2, source3],
  40. (values, oldValues) => {
  41. expectType<[string, string, number]>(values)
  42. expectType<[string | undefined, string | undefined, number | undefined]>(
  43. oldValues,
  44. )
  45. },
  46. { immediate: true },
  47. )
  48. // const array
  49. watch(
  50. [source, source2, source3] as const,
  51. (values, oldValues) => {
  52. expectType<Readonly<[string, string, number]>>(values)
  53. expectType<
  54. Readonly<[string | undefined, string | undefined, number | undefined]>
  55. >(oldValues)
  56. },
  57. { immediate: true },
  58. )
  59. // should provide correct ref.value inner type to callbacks
  60. const nestedRefSource = ref({
  61. foo: ref(1),
  62. })
  63. watch(nestedRefSource, (v, ov) => {
  64. expectType<{ foo: number }>(v)
  65. expectType<{ foo: number }>(ov)
  66. })
  67. const someRef = ref({ test: 'test' })
  68. const otherRef = ref({ a: 'b' })
  69. watch([someRef, otherRef], values => {
  70. const value1 = values[0]
  71. // no type error
  72. console.log(value1.test)
  73. const value2 = values[1]
  74. // no type error
  75. console.log(value2.a)
  76. })
  77. // #6135
  78. defineComponent({
  79. data() {
  80. return { a: 1 }
  81. },
  82. created() {
  83. this.$watch(
  84. () => this.a,
  85. (v, ov, onCleanup) => {
  86. expectType<number>(v)
  87. expectType<number>(ov)
  88. expectType<OnCleanup>(onCleanup)
  89. },
  90. )
  91. },
  92. })
  93. {
  94. //#7852
  95. type Steps = { step: '1' } | { step: '2' }
  96. const shallowUnionGenParam = shallowRef<Steps>({ step: '1' })
  97. const shallowUnionAsCast = shallowRef({ step: '1' } as Steps)
  98. watch(shallowUnionGenParam, value => {
  99. expectType<Steps>(value)
  100. })
  101. watch(shallowUnionAsCast, value => {
  102. expectType<Steps>(value)
  103. })
  104. }
  105. {
  106. // defineModel
  107. const bool = defineModel({ default: false })
  108. watch(bool, value => {
  109. expectType<boolean>(value)
  110. })
  111. const bool1 = defineModel<boolean>()
  112. watch(bool1, value => {
  113. expectType<boolean | undefined>(value)
  114. })
  115. const msg = defineModel<string>({ required: true })
  116. watch(msg, value => {
  117. expectType<string>(value)
  118. })
  119. const arr = defineModel<string[]>({ required: true })
  120. watch(arr, value => {
  121. expectType<string[]>(value)
  122. })
  123. const obj = defineModel<{ foo: string }>({ required: true })
  124. watch(obj, value => {
  125. expectType<{ foo: string }>(value)
  126. })
  127. }