From c2f762249cfb93e5db75a04817f5ebe95cbbcee3 Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Mon, 24 Feb 2025 14:34:22 +0800 Subject: [PATCH 1/5] fix(types): keep readonly infomation during unwrap refs --- packages/reactivity/src/ref.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 6b8d54181..6f1cacbd3 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -486,9 +486,15 @@ function propertyToRef( export interface RefUnwrapBailTypes {} export type ShallowUnwrapRef = { - [K in keyof T]: DistributeRef + readonly [K in keyof Pick>]: DistributeRef +} & { + [K in keyof Omit>]: DistributeRef } +type ReadonlyKeys = { + [K in keyof O]: O[K] extends Readonly ? K : never +}[keyof O] + type DistributeRef = T extends Ref ? V : T export type UnwrapRef = From 425ece0d5d292bd2a6352284f3894d5f5fc71b26 Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Mon, 24 Feb 2025 14:56:04 +0800 Subject: [PATCH 2/5] fix: use answer from stackoverflow --- packages/reactivity/src/ref.ts | 16 +++++++++++----- packages/shared/src/typeUtils.ts | 4 ++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 6f1cacbd3..c0e9c155b 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -1,5 +1,6 @@ import { type IfAny, + type IfEquals, hasChanged, isArray, isFunction, @@ -486,14 +487,19 @@ function propertyToRef( export interface RefUnwrapBailTypes {} export type ShallowUnwrapRef = { - readonly [K in keyof Pick>]: DistributeRef + [K in keyof Pick>]: DistributeRef } & { - [K in keyof Omit>]: DistributeRef + readonly [K in keyof Omit>]: DistributeRef } -type ReadonlyKeys = { - [K in keyof O]: O[K] extends Readonly ? K : never -}[keyof O] +type MutableKeys = { + [P in keyof T]-?: IfEquals< + { [Q in P]: T[P] }, + { -readonly [Q in P]: T[P] }, + P, + never + > +}[keyof T] type DistributeRef = T extends Ref ? V : T diff --git a/packages/shared/src/typeUtils.ts b/packages/shared/src/typeUtils.ts index f5b9e6ec3..ec8531e46 100644 --- a/packages/shared/src/typeUtils.ts +++ b/packages/shared/src/typeUtils.ts @@ -13,6 +13,10 @@ export type LooseRequired = { [P in keyof (T & Required)]: T[P] } // https://stackoverflow.com/questions/49927523/disallow-call-with-any/49928360#49928360 export type IfAny = 0 extends 1 & T ? Y : N +// https://stackoverflow.com/questions/52443276/how-to-exclude-getter-only-properties-from-type-in-typescript/52473108#52473108 +export type IfEquals = + (() => T extends A ? 1 : 2) extends () => T extends B ? 1 : 2 ? Y : N + export type IsKeyValues = IfAny< T, false, From ad29ea5ba14c78e026c2f002a4f36fedbb669771 Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Mon, 24 Feb 2025 15:38:30 +0800 Subject: [PATCH 3/5] fix: type --- packages/reactivity/src/ref.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index c0e9c155b..b0c70550d 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -493,10 +493,10 @@ export type ShallowUnwrapRef = { } type MutableKeys = { - [P in keyof T]-?: IfEquals< - { [Q in P]: T[P] }, - { -readonly [Q in P]: T[P] }, - P, + [K in keyof T]-?: IfEquals< + { [P in keyof T[K]]: T[K][P] }, + { -readonly [P in keyof T[K]]: T[K][P] }, + K, never > }[keyof T] From 4f6ee56cd809fb10e7d0f1cb16882f75df98a045 Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Mon, 24 Feb 2025 15:38:45 +0800 Subject: [PATCH 4/5] test: add case --- packages-private/dts-test/defineComponent.test-d.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages-private/dts-test/defineComponent.test-d.tsx b/packages-private/dts-test/defineComponent.test-d.tsx index fda3ca485..0aeed0331 100644 --- a/packages-private/dts-test/defineComponent.test-d.tsx +++ b/packages-private/dts-test/defineComponent.test-d.tsx @@ -11,6 +11,7 @@ import { defineComponent, h, reactive, + readonly, ref, withKeys, withModifiers, @@ -190,6 +191,7 @@ describe('with object props', () => { f: reactive({ g: ref('hello' as GT), }), + m: readonly(ref(1)) } }, provide() { @@ -259,6 +261,9 @@ describe('with object props', () => { // setup context properties should be mutable this.c = 2 + // @ts-expect-error setup context readonly properties should not be mutable + this.m = 2 + return null }, }) From 166a5c1eba7597d8f9d8f4c024b15b2f4dba0454 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 07:39:42 +0000 Subject: [PATCH 5/5] [autofix.ci] apply automated fixes --- packages-private/dts-test/defineComponent.test-d.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages-private/dts-test/defineComponent.test-d.tsx b/packages-private/dts-test/defineComponent.test-d.tsx index 0aeed0331..422897314 100644 --- a/packages-private/dts-test/defineComponent.test-d.tsx +++ b/packages-private/dts-test/defineComponent.test-d.tsx @@ -191,7 +191,7 @@ describe('with object props', () => { f: reactive({ g: ref('hello' as GT), }), - m: readonly(ref(1)) + m: readonly(ref(1)), } }, provide() {