2
0

reactivity.test-d.ts 3.7 KB

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