Skip to content

Commit

Permalink
fix(types): keep the original type when unwrapping markRaw (vuejs#3791
Browse files Browse the repository at this point in the history
)
  • Loading branch information
pikax authored and iwusong committed May 13, 2022
1 parent e436be8 commit be3bd0b
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 7 deletions.
6 changes: 4 additions & 2 deletions packages/reactivity/src/reactive.ts
Expand Up @@ -11,7 +11,7 @@ import {
shallowCollectionHandlers,
shallowReadonlyCollectionHandlers
} from './collectionHandlers'
import { UnwrapRefSimple, Ref } from './ref'
import { UnwrapRefSimple, Ref, RawSymbol } from './ref'

export const enum ReactiveFlags {
SKIP = '__v_skip',
Expand Down Expand Up @@ -241,7 +241,9 @@ export function toRaw<T>(observed: T): T {
return raw ? toRaw(raw) : observed
}

export function markRaw<T extends object>(value: T): T {
export function markRaw<T extends object>(
value: T
): T & { [RawSymbol]?: true } {
def(value, ReactiveFlags.SKIP, true)
return value
}
Expand Down
2 changes: 2 additions & 0 deletions packages/reactivity/src/ref.ts
Expand Up @@ -12,6 +12,7 @@ import { CollectionTypes } from './collectionHandlers'
import { createDep, Dep } from './dep'

declare const RefSymbol: unique symbol
export declare const RawSymbol: unique symbol

export interface Ref<T = any> {
value: T
Expand Down Expand Up @@ -291,6 +292,7 @@ export type UnwrapRefSimple<T> = T extends
| BaseTypes
| Ref
| RefUnwrapBailTypes[keyof RefUnwrapBailTypes]
| { [RawSymbol]?: true }
? T
: T extends Array<any>
? { [K in keyof T]: UnwrapRefSimple<T[K]> }
Expand Down
6 changes: 3 additions & 3 deletions test-dts/index.d.ts
Expand Up @@ -9,9 +9,9 @@ export function expectType<T>(value: T): void
export function expectError<T>(value: T): void
export function expectAssignable<T, T2 extends T = T>(value: T2): void

export type IsUnion<T, U extends T = T> = (T extends any
? (U extends T ? false : true)
: never) extends false
export type IsUnion<T, U extends T = T> = (
T extends any ? (U extends T ? false : true) : never
) extends false
? false
: true

Expand Down
42 changes: 40 additions & 2 deletions test-dts/reactivity.test-d.ts
@@ -1,5 +1,14 @@
import { shallowReadonly } from '@vue/reactivity'
import { ref, readonly, describe, expectError, expectType, Ref } from './index'
import {
ref,
readonly,
shallowReadonly,
describe,
expectError,
expectType,
Ref,
reactive,
markRaw
} from './index'

describe('should support DeepReadonly', () => {
const r = readonly({ obj: { k: 'v' } })
Expand All @@ -15,6 +24,35 @@ describe('readonly ref', () => {
expectType<Ref>(r)
})

describe('should support markRaw', () => {
class Test<T> {
item = {} as Ref<T>
}
const test = new Test<number>()
const plain = {
ref: ref(1)
}

const r = reactive({
class: {
raw: markRaw(test),
reactive: test
},
plain: {
raw: markRaw(plain),
reactive: plain
}
})

expectType<Test<number>>(r.class.raw)
// @ts-expect-error it should unwrap
expectType<Test<number>>(r.class.reactive)

expectType<Ref<number>>(r.plain.raw.ref)
// @ts-expect-error it should unwrap
expectType<Ref<number>>(r.plain.reactive.ref)
})

describe('shallowReadonly ref unwrap', () => {
const r = shallowReadonly({ count: { n: ref(1) } })
// @ts-expect-error
Expand Down

0 comments on commit be3bd0b

Please sign in to comment.