feat(types/reactivity): use DeepReadonly type for readonly return type (#1462)

close #1452
This commit is contained in:
Pick 2020-07-15 21:27:21 +08:00 committed by GitHub
parent 246ec5c594
commit b772bba558
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 2 deletions

View File

@ -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

View File

@ -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,

View 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'))
})