From e816812f10b9e3a375eef8dffd617d7f08b23c00 Mon Sep 17 00:00:00 2001 From: HeYunfei Date: Wed, 26 Oct 2022 16:27:42 +0800 Subject: [PATCH] fix(types): should unwrap tuple correctly (#3820) fix #3819 --- packages/reactivity/src/ref.ts | 13 ++-- test-dts/reactivity.test-d.ts | 135 ++++++++++++++++++--------------- 2 files changed, 78 insertions(+), 70 deletions(-) diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 5843b3f63ae..2632160b318 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -280,13 +280,10 @@ export interface RefUnwrapBailTypes {} export type ShallowUnwrapRef = { [K in keyof T]: T[K] extends Ref - ? V - : // if `V` is `unknown` that means it does not extend `Ref` and is undefined - T[K] extends Ref | undefined - ? unknown extends V - ? undefined - : V | undefined - : T[K] + ? V // if `V` is `unknown` that means it does not extend `Ref` and is undefined + : T[K] extends Ref | undefined + ? unknown extends V ? undefined : V | undefined + : T[K] } export type UnwrapRef = T extends ShallowRef @@ -303,7 +300,7 @@ export type UnwrapRefSimple = T extends | RefUnwrapBailTypes[keyof RefUnwrapBailTypes] | { [RawSymbol]?: true } ? T - : T extends Array + : T extends ReadonlyArray ? { [K in keyof T]: UnwrapRefSimple } : T extends object & { [ShallowReactiveMarker]?: never } ? { diff --git a/test-dts/reactivity.test-d.ts b/test-dts/reactivity.test-d.ts index 0499c6da287..8722441ec14 100644 --- a/test-dts/reactivity.test-d.ts +++ b/test-dts/reactivity.test-d.ts @@ -1,62 +1,73 @@ -import { - ref, - readonly, - shallowReadonly, - describe, - expectError, - expectType, - Ref, - reactive, - markRaw -} 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')) -}) - -// #4180 -describe('readonly ref', () => { - const r = readonly(ref({ count: 1 })) - expectType(r) -}) - -describe('should support markRaw', () => { - class Test { - item = {} as Ref - } - const test = new Test() - const plain = { - ref: ref(1) - } - - const r = reactive({ - class: { - raw: markRaw(test), - reactive: test - }, - plain: { - raw: markRaw(plain), - reactive: plain - } - }) - - expectType>(r.class.raw) - // @ts-expect-error it should unwrap - expectType>(r.class.reactive) - - expectType>(r.plain.raw.ref) - // @ts-expect-error it should unwrap - expectType>(r.plain.reactive.ref) -}) - -describe('shallowReadonly ref unwrap', () => { - const r = shallowReadonly({ count: { n: ref(1) } }) - // @ts-expect-error - r.count = 2 - expectType(r.count.n) - r.count.n.value = 123 -}) +import { + ref, + readonly, + shallowReadonly, + describe, + expectError, + expectType, + Ref, + reactive, + markRaw +} 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')) +}) + +// #4180 +describe('readonly ref', () => { + const r = readonly(ref({ count: 1 })) + expectType(r) +}) + +describe('should support markRaw', () => { + class Test { + item = {} as Ref + } + const test = new Test() + const plain = { + ref: ref(1) + } + + const r = reactive({ + class: { + raw: markRaw(test), + reactive: test + }, + plain: { + raw: markRaw(plain), + reactive: plain + } + }) + + expectType>(r.class.raw) + // @ts-expect-error it should unwrap + expectType>(r.class.reactive) + + expectType>(r.plain.raw.ref) + // @ts-expect-error it should unwrap + expectType>(r.plain.reactive.ref) +}) + +describe('shallowReadonly ref unwrap', () => { + const r = shallowReadonly({ count: { n: ref(1) } }) + // @ts-expect-error + r.count = 2 + expectType(r.count.n) + r.count.n.value = 123 +}) + +// #3819 +describe('should unwrap tuple correctly', () => { + const readonlyTuple = [ref(0)] as const + const reactiveReadonlyTuple = reactive(readonlyTuple) + expectType>(reactiveReadonlyTuple[0]) + + const tuple: [Ref] = [ref(0)] + const reactiveTuple = reactive(tuple) + expectType>(reactiveTuple[0]) +})