reactivity.test-d.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import {
  2. type Ref,
  3. markRaw,
  4. reactive,
  5. readonly,
  6. ref,
  7. shallowReadonly,
  8. } from 'vue'
  9. import { describe, expectType } from './utils'
  10. describe('should support DeepReadonly', () => {
  11. const r = readonly({ obj: { k: 'v' } })
  12. // @ts-expect-error
  13. r.obj = {}
  14. // @ts-expect-error
  15. r.obj.k = 'x'
  16. })
  17. // #4180
  18. describe('readonly ref', () => {
  19. const r = readonly(ref({ count: 1 }))
  20. expectType<Ref>(r)
  21. })
  22. describe('should support markRaw', () => {
  23. class Test<T> {
  24. item = {} as Ref<T>
  25. }
  26. const test = new Test<number>()
  27. const plain = {
  28. ref: ref(1),
  29. }
  30. const r = reactive({
  31. class: {
  32. raw: markRaw(test),
  33. reactive: test,
  34. },
  35. plain: {
  36. raw: markRaw(plain),
  37. reactive: plain,
  38. },
  39. })
  40. expectType<Test<number>>(r.class.raw)
  41. // @ts-expect-error it should unwrap
  42. expectType<Test<number>>(r.class.reactive)
  43. expectType<Ref<number>>(r.plain.raw.ref)
  44. // @ts-expect-error it should unwrap
  45. expectType<Ref<number>>(r.plain.reactive.ref)
  46. })
  47. describe('shallowReadonly ref unwrap', () => {
  48. const r = shallowReadonly({ count: { n: ref(1) } })
  49. // @ts-expect-error
  50. r.count = 2
  51. expectType<Ref>(r.count.n)
  52. r.count.n.value = 123
  53. })
  54. // #3819
  55. describe('should unwrap tuple correctly', () => {
  56. const readonlyTuple = [ref(0)] as const
  57. const reactiveReadonlyTuple = reactive(readonlyTuple)
  58. expectType<Ref<number>>(reactiveReadonlyTuple[0])
  59. const tuple: [Ref<number>] = [ref(0)]
  60. const reactiveTuple = reactive(tuple)
  61. expectType<Ref<number>>(reactiveTuple[0])
  62. })
  63. describe('should unwrap Map correctly', () => {
  64. const map = reactive(new Map<string, Ref<number>>())
  65. expectType<Ref<number>>(map.get('a')!)
  66. const map2 = reactive(new Map<string, { wrap: Ref<number> }>())
  67. expectType<number>(map2.get('a')!.wrap)
  68. const wm = reactive(new WeakMap<object, Ref<number>>())
  69. expectType<Ref<number>>(wm.get({})!)
  70. const wm2 = reactive(new WeakMap<object, { wrap: Ref<number> }>())
  71. expectType<number>(wm2.get({})!.wrap)
  72. })
  73. describe('should unwrap extended Map correctly', () => {
  74. class ExtendendMap1 extends Map<string, { wrap: Ref<number> }> {
  75. foo = ref('foo')
  76. bar = 1
  77. }
  78. const emap1 = reactive(new ExtendendMap1())
  79. expectType<string>(emap1.foo)
  80. expectType<number>(emap1.bar)
  81. expectType<number>(emap1.get('a')!.wrap)
  82. })
  83. describe('should unwrap Set correctly', () => {
  84. const set = reactive(new Set<Ref<number>>())
  85. expectType<Set<Ref<number>>>(set)
  86. const set2 = reactive(new Set<{ wrap: Ref<number> }>())
  87. expectType<Set<{ wrap: number }>>(set2)
  88. const ws = reactive(new WeakSet<Ref<number>>())
  89. expectType<WeakSet<Ref<number>>>(ws)
  90. const ws2 = reactive(new WeakSet<{ wrap: Ref<number> }>())
  91. expectType<WeakSet<{ wrap: number }>>(ws2)
  92. })
  93. describe('should unwrap extended Set correctly', () => {
  94. class ExtendendSet1 extends Set<{ wrap: Ref<number> }> {
  95. foo = ref('foo')
  96. bar = 1
  97. }
  98. const eset1 = reactive(new ExtendendSet1())
  99. expectType<string>(eset1.foo)
  100. expectType<number>(eset1.bar)
  101. })
  102. describe('should not error when assignment', () => {
  103. const arr = reactive([''])
  104. let record: Record<number, string>
  105. record = arr
  106. expectType<string>(record[0])
  107. let record2: { [key: number]: string }
  108. record2 = arr
  109. expectType<string>(record2[0])
  110. })