ref.test-d.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import {
  2. Ref,
  3. ref,
  4. shallowRef,
  5. isRef,
  6. unref,
  7. reactive,
  8. expectType,
  9. proxyRefs
  10. } from './index'
  11. function plainType(arg: number | Ref<number>) {
  12. // ref coercing
  13. const coerced = ref(arg)
  14. expectType<Ref<number>>(coerced)
  15. // isRef as type guard
  16. if (isRef(arg)) {
  17. expectType<Ref<number>>(arg)
  18. }
  19. // ref unwrapping
  20. expectType<number>(unref(arg))
  21. // ref inner type should be unwrapped
  22. const nestedRef = ref({
  23. foo: ref(1)
  24. })
  25. expectType<Ref<{ foo: number }>>(nestedRef)
  26. expectType<{ foo: number }>(nestedRef.value)
  27. // ref boolean
  28. const falseRef = ref(false)
  29. expectType<Ref<boolean>>(falseRef)
  30. expectType<boolean>(falseRef.value)
  31. // ref true
  32. const trueRef = ref<true>(true)
  33. expectType<Ref<true>>(trueRef)
  34. expectType<true>(trueRef.value)
  35. // tuple
  36. expectType<[number, string]>(unref(ref([1, '1'])))
  37. interface IteratorFoo {
  38. [Symbol.iterator]: any
  39. }
  40. // with symbol
  41. expectType<Ref<IteratorFoo | null | undefined>>(
  42. ref<IteratorFoo | null | undefined>()
  43. )
  44. // should not unwrap ref inside arrays
  45. const arr = ref([1, new Map<string, any>(), ref('1')]).value
  46. const value = arr[0]
  47. if (isRef(value)) {
  48. expectType<Ref>(value)
  49. } else if (typeof value === 'number') {
  50. expectType<number>(value)
  51. } else {
  52. // should narrow down to Map type
  53. // and not contain any Ref type
  54. expectType<Map<string, any>>(value)
  55. }
  56. // should still unwrap in objects nested in arrays
  57. const arr2 = ref([{ a: ref(1) }]).value
  58. expectType<number>(arr2[0].a)
  59. }
  60. plainType(1)
  61. function bailType(arg: HTMLElement | Ref<HTMLElement>) {
  62. // ref coercing
  63. const coerced = ref(arg)
  64. expectType<Ref<HTMLElement>>(coerced)
  65. // isRef as type guard
  66. if (isRef(arg)) {
  67. expectType<Ref<HTMLElement>>(arg)
  68. }
  69. // ref unwrapping
  70. expectType<HTMLElement>(unref(arg))
  71. // ref inner type should be unwrapped
  72. // eslint-disable-next-line no-restricted-globals
  73. const nestedRef = ref({ foo: ref(document.createElement('DIV')) })
  74. expectType<Ref<{ foo: HTMLElement }>>(nestedRef)
  75. expectType<{ foo: HTMLElement }>(nestedRef.value)
  76. }
  77. // eslint-disable-next-line no-restricted-globals
  78. const el = document.createElement('DIV')
  79. bailType(el)
  80. function withSymbol() {
  81. const customSymbol = Symbol()
  82. const obj = {
  83. [Symbol.asyncIterator]: { a: 1 },
  84. [Symbol.unscopables]: { b: '1' },
  85. [customSymbol]: { c: [1, 2, 3] }
  86. }
  87. const objRef = ref(obj)
  88. expectType<{ a: number }>(objRef.value[Symbol.asyncIterator])
  89. expectType<{ b: string }>(objRef.value[Symbol.unscopables])
  90. expectType<{ c: Array<number> }>(objRef.value[customSymbol])
  91. }
  92. withSymbol()
  93. const state = reactive({
  94. foo: {
  95. value: 1,
  96. label: 'bar'
  97. }
  98. })
  99. expectType<string>(state.foo.label)
  100. // shallowRef
  101. type Status = 'initial' | 'ready' | 'invalidating'
  102. const shallowStatus = shallowRef<Status>('initial')
  103. if (shallowStatus.value === 'initial') {
  104. expectType<Ref<Status>>(shallowStatus)
  105. expectType<Status>(shallowStatus.value)
  106. shallowStatus.value = 'invalidating'
  107. }
  108. const refStatus = ref<Status>('initial')
  109. if (refStatus.value === 'initial') {
  110. expectType<Ref<Status>>(shallowStatus)
  111. expectType<Status>(shallowStatus.value)
  112. refStatus.value = 'invalidating'
  113. }
  114. // proxyRefs: should return `reactive` directly
  115. const r1 = reactive({
  116. k: 'v'
  117. })
  118. const p1 = proxyRefs(r1)
  119. expectType<typeof r1>(p1)
  120. // proxyRefs: `ShallowUnwrapRef`
  121. const r2 = {
  122. a: ref(1),
  123. obj: {
  124. k: ref('foo')
  125. }
  126. }
  127. const p2 = proxyRefs(r2)
  128. expectType<number>(p2.a)
  129. expectType<Ref<string>>(p2.obj.k)