diff --git a/packages-private/dts-test/reactivity.test-d.ts b/packages-private/dts-test/reactivity.test-d.ts index f5b9176729c..eeded3a7be6 100644 --- a/packages-private/dts-test/reactivity.test-d.ts +++ b/packages-private/dts-test/reactivity.test-d.ts @@ -5,6 +5,7 @@ import { readonly, ref, shallowReadonly, + toRaw, } from 'vue' import { describe, expectType } from './utils' @@ -130,3 +131,23 @@ describe('should not error when assignment', () => { record2 = arr expectType(record2[0]) }) + +// #7478 +describe('readonly raw type', () => { + type Foo = { a: number; b: string; c: { d: number } } + const foo: Foo = { + a: 1, + b: 'b', + c: { d: 2 }, + } + + // readonly + const r = readonly(foo) + const rawObj = toRaw(r) + expectType(rawObj) + + // shallowReadonly + const shallowR = shallowReadonly(foo) + const shallowRawObj = toRaw(shallowR) + expectType(shallowRawObj) +}) diff --git a/packages/reactivity/src/reactive.ts b/packages/reactivity/src/reactive.ts index 729c854965e..a41489790b5 100644 --- a/packages/reactivity/src/reactive.ts +++ b/packages/reactivity/src/reactive.ts @@ -15,6 +15,15 @@ import type { RawSymbol, Ref, UnwrapRefSimple } from './ref' import { ReactiveFlags } from './constants' import { warn } from './warning' +declare const ReadonlyRawSymbol: unique symbol + +interface ReadonlyRaw { + /** + * Original type used to hold readonly function parameters + */ + [ReadonlyRawSymbol]: T +} + export interface Target { [ReactiveFlags.SKIP]?: boolean [ReactiveFlags.IS_REACTIVE]?: boolean @@ -204,7 +213,7 @@ export type DeepReadonly = T extends Builtin */ export function readonly( target: T, -): DeepReadonly> { +): DeepReadonly> & ReadonlyRaw { return createReactiveObject( target, true, @@ -244,7 +253,9 @@ export function readonly( * @param target - The source object. * @see {@link https://vuejs.org/api/reactivity-advanced.html#shallowreadonly} */ -export function shallowReadonly(target: T): Readonly { +export function shallowReadonly( + target: T, +): Readonly & ReadonlyRaw { return createReactiveObject( target, true, @@ -375,6 +386,10 @@ export function isProxy(value: any): boolean { * @param observed - The object for which the "raw" value is requested. * @see {@link https://vuejs.org/api/reactivity-advanced.html#toraw} */ +export function toRaw>( + observed: T, +): T[typeof ReadonlyRawSymbol] +export function toRaw(observed: T): T export function toRaw(observed: T): T { const raw = observed && (observed as Target)[ReactiveFlags.RAW] return raw ? toRaw(raw) : observed pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy