Skip to content

Commit

Permalink
feat(types/reactivity): use DeepReadonly type for readonly return…
Browse files Browse the repository at this point in the history
… type (#1462)

close #1452
  • Loading branch information
Pick committed Jul 15, 2020
1 parent 246ec5c commit b772bba
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`).

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

Expand Down
24 changes: 23 additions & 1 deletion packages/reactivity/src/reactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>(
target: T
): Readonly<UnwrapNestedRefs<T>> {
): DeepReadonly<UnwrapNestedRefs<T>> {
return createReactiveObject(
target,
true,
Expand Down
9 changes: 9 additions & 0 deletions test-dts/reactivity.test-d.ts
Original file line number Diff line number Diff line change
@@ -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'))
})

0 comments on commit b772bba

Please sign in to comment.