Skip to content

Commit b772bba

Browse files
author
Pick
authored
feat(types/reactivity): use DeepReadonly type for readonly return type (#1462)
close #1452
1 parent 246ec5c commit b772bba

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

.github/contributing.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ Test coverage is continuously deployed at https://vue-next-coverage.netlify.app/
244244

245245
This project uses [tsd](https://github.com/SamVerschueren/tsd) to test the built definition files (`*.d.ts`).
246246

247-
Type tests are located in the `test-dts` directory. To run the dts tests, run `yarn test-dts`. Note that the type test requires all relevant `*.d.ts` files to be built first (and the script does it for you). Once the `d.ts` files are built and up-to-date, the tests can be re-run by simply running `./node_modules/.bin/tsd`.
247+
Type tests are located in the `test-dts` directory. To run the dts tests, run `yarn test-dts`. Note that the type test requires all relevant `*.d.ts` files to be built first (and the script does it for you). Once the `d.ts` files are built and up-to-date, the tests can be re-run by simply running `yarn test-dts`.
248248

249249
## Financial Contribution
250250

packages/reactivity/src/reactive.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,31 @@ export function shallowReactive<T extends object>(target: T): T {
7272
)
7373
}
7474

75+
type Primitive = string | number | boolean | bigint | symbol | undefined | null
76+
type Builtin = Primitive | Function | Date | Error | RegExp
77+
type DeepReadonly<T> = T extends Builtin
78+
? T
79+
: T extends Map<infer K, infer V>
80+
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
81+
: T extends ReadonlyMap<infer K, infer V>
82+
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
83+
: T extends WeakMap<infer K, infer V>
84+
? WeakMap<DeepReadonly<K>, DeepReadonly<V>>
85+
: T extends Set<infer U>
86+
? ReadonlySet<DeepReadonly<U>>
87+
: T extends ReadonlySet<infer U>
88+
? ReadonlySet<DeepReadonly<U>>
89+
: T extends WeakSet<infer U>
90+
? WeakSet<DeepReadonly<U>>
91+
: T extends Promise<infer U>
92+
? Promise<DeepReadonly<U>>
93+
: T extends {}
94+
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
95+
: Readonly<T>
96+
7597
export function readonly<T extends object>(
7698
target: T
77-
): Readonly<UnwrapNestedRefs<T>> {
99+
): DeepReadonly<UnwrapNestedRefs<T>> {
78100
return createReactiveObject(
79101
target,
80102
true,

test-dts/reactivity.test-d.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { readonly, describe, expectError } from './index'
2+
3+
describe('should support DeepReadonly', () => {
4+
const r = readonly({ obj: { k: 'v' } })
5+
// @ts-expect-error
6+
expectError((r.obj = {}))
7+
// @ts-expect-error
8+
expectError((r.obj.k = 'x'))
9+
})

0 commit comments

Comments
 (0)