From 9d6fc279d7a6b4b0da715b318a27dce8b92d8912 Mon Sep 17 00:00:00 2001 From: chenyi Date: Wed, 21 Jul 2021 13:38:19 +0800 Subject: [PATCH 1/2] types(reactivity): Simplify the SymbolExtract --- packages/reactivity/src/ref.ts | 42 ++++++++++++++-------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 010fb8d85bd..d169268fe32 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -285,30 +285,22 @@ type UnwrapRefSimple = T extends // Extract all known symbols from an object // when unwrapping Object the symbols are not `in keyof`, this should cover all the // known symbols -type SymbolExtract = (T extends { [Symbol.asyncIterator]: infer V } - ? { [Symbol.asyncIterator]: V } - : {}) & - (T extends { [Symbol.hasInstance]: infer V } - ? { [Symbol.hasInstance]: V } - : {}) & - (T extends { [Symbol.isConcatSpreadable]: infer V } - ? { [Symbol.isConcatSpreadable]: V } - : {}) & - (T extends { [Symbol.iterator]: infer V } ? { [Symbol.iterator]: V } : {}) & - (T extends { [Symbol.match]: infer V } ? { [Symbol.match]: V } : {}) & - (T extends { [Symbol.matchAll]: infer V } ? { [Symbol.matchAll]: V } : {}) & - (T extends { [Symbol.replace]: infer V } ? { [Symbol.replace]: V } : {}) & - (T extends { [Symbol.search]: infer V } ? { [Symbol.search]: V } : {}) & - (T extends { [Symbol.species]: infer V } ? { [Symbol.species]: V } : {}) & - (T extends { [Symbol.split]: infer V } ? { [Symbol.split]: V } : {}) & - (T extends { [Symbol.toPrimitive]: infer V } - ? { [Symbol.toPrimitive]: V } - : {}) & - (T extends { [Symbol.toStringTag]: infer V } - ? { [Symbol.toStringTag]: V } - : {}) & - (T extends { [Symbol.unscopables]: infer V } - ? { [Symbol.unscopables]: V } - : {}) +type Symbols = { + [Symbol.asyncIterator]: unknown + [Symbol.hasInstance]: unknown + [Symbol.isConcatSpreadable]: unknown + [Symbol.iterator]: unknown + [Symbol.match]: unknown + [Symbol.matchAll]: unknown + [Symbol.replace]: unknown + [Symbol.search]: unknown + [Symbol.species]: unknown + [Symbol.split]: unknown + [Symbol.toPrimitive]: unknown + [Symbol.toStringTag]: unknown + [Symbol.unscopables]: unknown +} + +type SymbolExtract = { [K in keyof T & keyof Symbols]: T[K] } type UnwrappedObject = { [P in keyof T]: UnwrapRef } & SymbolExtract From 150b72e7b1391b05a13c27d6f61bc8195c28276c Mon Sep 17 00:00:00 2001 From: chenyi Date: Sat, 24 Jul 2021 22:36:19 +0800 Subject: [PATCH 2/2] types(reactivity): Simplify the UnwrapRefSimple --- packages/reactivity/__tests__/ref.spec.ts | 40 +++++++++++++++++++---- packages/reactivity/src/ref.ts | 27 ++------------- test-dts/ref.test-d.ts | 38 +++++++++++++++++---- 3 files changed, 69 insertions(+), 36 deletions(-) diff --git a/packages/reactivity/__tests__/ref.spec.ts b/packages/reactivity/__tests__/ref.spec.ts index 94ad47ec63d..b416c37ac02 100644 --- a/packages/reactivity/__tests__/ref.spec.ts +++ b/packages/reactivity/__tests__/ref.spec.ts @@ -152,16 +152,44 @@ describe('reactivity/ref', () => { it('should keep symbols', () => { const customSymbol = Symbol() const obj = { - [Symbol.asyncIterator]: { a: 1 }, - [Symbol.unscopables]: { b: '1' }, - [customSymbol]: { c: [1, 2, 3] } + [Symbol.asyncIterator]: ref(1), + [Symbol.hasInstance]: { a: ref('a') }, + [Symbol.isConcatSpreadable]: { b: ref(true) }, + [Symbol.iterator]: [ref(1)], + [Symbol.match]: new Set>(), + [Symbol.matchAll]: new Map>(), + [Symbol.replace]: { arr: [ref('a')] }, + [Symbol.search]: { set: new Set>() }, + [Symbol.species]: { map: new Map>() }, + [Symbol.split]: new WeakSet>(), + [Symbol.toPrimitive]: new WeakMap, string>(), + [Symbol.toStringTag]: { weakSet: new WeakSet>() }, + [Symbol.unscopables]: { weakMap: new WeakMap, string>() }, + [customSymbol]: { arr: [ref(1)] } } const objRef = ref(obj) - expect(objRef.value[Symbol.asyncIterator]).toBe(obj[Symbol.asyncIterator]) - expect(objRef.value[Symbol.unscopables]).toBe(obj[Symbol.unscopables]) - expect(objRef.value[customSymbol]).toStrictEqual(obj[customSymbol]) + const keys: (keyof typeof obj)[] = [ + Symbol.asyncIterator, + Symbol.hasInstance, + Symbol.isConcatSpreadable, + Symbol.iterator, + Symbol.match, + Symbol.matchAll, + Symbol.replace, + Symbol.search, + Symbol.species, + Symbol.split, + Symbol.toPrimitive, + Symbol.toStringTag, + Symbol.unscopables, + customSymbol + ] + + keys.forEach(key => { + expect(objRef.value[key]).toStrictEqual(obj[key]) + }) }) test('unref', () => { diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index d169268fe32..b00ce9cf9d9 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -279,28 +279,7 @@ type UnwrapRefSimple = T extends : T extends Array ? { [K in keyof T]: UnwrapRefSimple } : T extends object - ? UnwrappedObject + ? { + [P in keyof T]: P extends symbol ? T[P] : UnwrapRef + } : T - -// Extract all known symbols from an object -// when unwrapping Object the symbols are not `in keyof`, this should cover all the -// known symbols -type Symbols = { - [Symbol.asyncIterator]: unknown - [Symbol.hasInstance]: unknown - [Symbol.isConcatSpreadable]: unknown - [Symbol.iterator]: unknown - [Symbol.match]: unknown - [Symbol.matchAll]: unknown - [Symbol.replace]: unknown - [Symbol.search]: unknown - [Symbol.species]: unknown - [Symbol.split]: unknown - [Symbol.toPrimitive]: unknown - [Symbol.toStringTag]: unknown - [Symbol.unscopables]: unknown -} - -type SymbolExtract = { [K in keyof T & keyof Symbols]: T[K] } - -type UnwrappedObject = { [P in keyof T]: UnwrapRef } & SymbolExtract diff --git a/test-dts/ref.test-d.ts b/test-dts/ref.test-d.ts index 74bb78298da..c7f1283720e 100644 --- a/test-dts/ref.test-d.ts +++ b/test-dts/ref.test-d.ts @@ -101,16 +101,42 @@ bailType(el) function withSymbol() { const customSymbol = Symbol() const obj = { - [Symbol.asyncIterator]: { a: 1 }, - [Symbol.unscopables]: { b: '1' }, - [customSymbol]: { c: [1, 2, 3] } + [Symbol.asyncIterator]: ref(1), + [Symbol.hasInstance]: { a: ref('a') }, + [Symbol.isConcatSpreadable]: { b: ref(true) }, + [Symbol.iterator]: [ref(1)], + [Symbol.match]: new Set>(), + [Symbol.matchAll]: new Map>(), + [Symbol.replace]: { arr: [ref('a')] }, + [Symbol.search]: { set: new Set>() }, + [Symbol.species]: { map: new Map>() }, + [Symbol.split]: new WeakSet>(), + [Symbol.toPrimitive]: new WeakMap, string>(), + [Symbol.toStringTag]: { weakSet: new WeakSet>() }, + [Symbol.unscopables]: { weakMap: new WeakMap, string>() }, + [customSymbol]: { arr: [ref(1)] } } const objRef = ref(obj) - expectType<{ a: number }>(objRef.value[Symbol.asyncIterator]) - expectType<{ b: string }>(objRef.value[Symbol.unscopables]) - expectType<{ c: Array }>(objRef.value[customSymbol]) + expectType>(objRef.value[Symbol.asyncIterator]) + expectType<{ a: Ref }>(objRef.value[Symbol.hasInstance]) + expectType<{ b: Ref }>(objRef.value[Symbol.isConcatSpreadable]) + expectType[]>(objRef.value[Symbol.iterator]) + expectType>>(objRef.value[Symbol.match]) + expectType>>(objRef.value[Symbol.matchAll]) + expectType<{ arr: Ref[] }>(objRef.value[Symbol.replace]) + expectType<{ set: Set> }>(objRef.value[Symbol.search]) + expectType<{ map: Map> }>(objRef.value[Symbol.species]) + expectType>>(objRef.value[Symbol.split]) + expectType, string>>(objRef.value[Symbol.toPrimitive]) + expectType<{ weakSet: WeakSet> }>( + objRef.value[Symbol.toStringTag] + ) + expectType<{ weakMap: WeakMap, string> }>( + objRef.value[Symbol.unscopables] + ) + expectType<{ arr: Ref[] }>(objRef.value[customSymbol]) } withSymbol()