import { type Ref, markRaw, reactive, readonly, ref, shallowReactive, shallowReadonly, } from 'vue' import { describe, expectType } from './utils' describe('should support DeepReadonly', () => { const r = readonly({ obj: { k: 'v' } }) // @ts-expect-error r.obj = {} // @ts-expect-error r.obj.k = 'x' }) // #4180 describe('readonly ref', () => { const r = readonly(ref({ count: 1 })) expectType(r) }) describe('should support markRaw', () => { class Test { item = {} as Ref } const test = new Test() const plain = { ref: ref(1), } const r = reactive({ class: { raw: markRaw(test), reactive: test, }, plain: { raw: markRaw(plain), reactive: plain, }, }) expectType>(r.class.raw) // @ts-expect-error it should unwrap expectType>(r.class.reactive) expectType>(r.plain.raw.ref) // @ts-expect-error it should unwrap expectType>(r.plain.reactive.ref) }) describe('shallowReadonly ref unwrap', () => { const r = shallowReadonly({ count: { n: ref(1) } }) // @ts-expect-error r.count = 2 expectType(r.count.n) r.count.n.value = 123 }) // #3819 describe('should unwrap tuple correctly', () => { const readonlyTuple = [ref(0)] as const const reactiveReadonlyTuple = reactive(readonlyTuple) expectType>(reactiveReadonlyTuple[0]) const tuple: [Ref] = [ref(0)] const reactiveTuple = reactive(tuple) expectType>(reactiveTuple[0]) }) describe('should unwrap Map correctly', () => { const map = reactive(new Map>()) expectType>(map.get('a')!) const map2 = reactive(new Map }>()) expectType(map2.get('a')!.wrap) const wm = reactive(new WeakMap>()) expectType>(wm.get({})!) const wm2 = reactive(new WeakMap }>()) expectType(wm2.get({})!.wrap) }) describe('should unwrap extended Map correctly', () => { class ExtendendMap1 extends Map }> { foo = ref('foo') bar = 1 } const emap1 = reactive(new ExtendendMap1()) expectType(emap1.foo) expectType(emap1.bar) expectType(emap1.get('a')!.wrap) }) describe('should unwrap Set correctly', () => { const set = reactive(new Set>()) expectType>>(set) const set2 = reactive(new Set<{ wrap: Ref }>()) expectType>(set2) const ws = reactive(new WeakSet>()) expectType>>(ws) const ws2 = reactive(new WeakSet<{ wrap: Ref }>()) expectType>(ws2) }) describe('should unwrap extended Set correctly', () => { class ExtendendSet1 extends Set<{ wrap: Ref }> { foo = ref('foo') bar = 1 } const eset1 = reactive(new ExtendendSet1()) expectType(eset1.foo) expectType(eset1.bar) }) describe('should not error when assignment', () => { const arr = reactive(['']) let record: Record record = arr expectType(record[0]) let record2: { [key: number]: string } record2 = arr expectType(record2[0]) }) describe('shallowReactive marker should not leak into value unions', () => { const state = shallowReactive({ a: { title: 'A' }, b: { title: 'B' }, }) const value = {} as (typeof state)[keyof typeof state] expectType(value.title) }) describe('shallowReactive type should accept plain object assignment', () => { const shallow = shallowReactive({ a: 1, b: 2 }) let values: typeof shallow values = { a: 1, b: 2 } })