feat(types/reactivity): use DeepReadonly
type for readonly
return type (#1462)
close #1452
This commit is contained in:
parent
246ec5c594
commit
b772bba558
2
.github/contributing.md
vendored
2
.github/contributing.md
vendored
@ -244,7 +244,7 @@ Test coverage is continuously deployed at https://vue-next-coverage.netlify.app/
|
|||||||
|
|
||||||
This project uses [tsd](https://github.com/SamVerschueren/tsd) to test the built definition files (`*.d.ts`).
|
This project uses [tsd](https://github.com/SamVerschueren/tsd) to test the built definition files (`*.d.ts`).
|
||||||
|
|
||||||
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`.
|
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`.
|
||||||
|
|
||||||
## Financial Contribution
|
## Financial Contribution
|
||||||
|
|
||||||
|
@ -72,9 +72,31 @@ export function shallowReactive<T extends object>(target: T): T {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Primitive = string | number | boolean | bigint | symbol | undefined | null
|
||||||
|
type Builtin = Primitive | Function | Date | Error | RegExp
|
||||||
|
type DeepReadonly<T> = T extends Builtin
|
||||||
|
? T
|
||||||
|
: T extends Map<infer K, infer V>
|
||||||
|
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
|
||||||
|
: T extends ReadonlyMap<infer K, infer V>
|
||||||
|
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
|
||||||
|
: T extends WeakMap<infer K, infer V>
|
||||||
|
? WeakMap<DeepReadonly<K>, DeepReadonly<V>>
|
||||||
|
: T extends Set<infer U>
|
||||||
|
? ReadonlySet<DeepReadonly<U>>
|
||||||
|
: T extends ReadonlySet<infer U>
|
||||||
|
? ReadonlySet<DeepReadonly<U>>
|
||||||
|
: T extends WeakSet<infer U>
|
||||||
|
? WeakSet<DeepReadonly<U>>
|
||||||
|
: T extends Promise<infer U>
|
||||||
|
? Promise<DeepReadonly<U>>
|
||||||
|
: T extends {}
|
||||||
|
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
|
||||||
|
: Readonly<T>
|
||||||
|
|
||||||
export function readonly<T extends object>(
|
export function readonly<T extends object>(
|
||||||
target: T
|
target: T
|
||||||
): Readonly<UnwrapNestedRefs<T>> {
|
): DeepReadonly<UnwrapNestedRefs<T>> {
|
||||||
return createReactiveObject(
|
return createReactiveObject(
|
||||||
target,
|
target,
|
||||||
true,
|
true,
|
||||||
|
9
test-dts/reactivity.test-d.ts
Normal file
9
test-dts/reactivity.test-d.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { readonly, describe, expectError } from './index'
|
||||||
|
|
||||||
|
describe('should support DeepReadonly', () => {
|
||||||
|
const r = readonly({ obj: { k: 'v' } })
|
||||||
|
// @ts-expect-error
|
||||||
|
expectError((r.obj = {}))
|
||||||
|
// @ts-expect-error
|
||||||
|
expectError((r.obj.k = 'x'))
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user