Ver Fonte

types(reactivity): Simplify the SymbolExtract (#4162)

Pick há 4 anos atrás
pai
commit
b79e4ca717

+ 34 - 6
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<Ref<number>>(),
+      [Symbol.matchAll]: new Map<number, Ref<string>>(),
+      [Symbol.replace]: { arr: [ref('a')] },
+      [Symbol.search]: { set: new Set<Ref<number>>() },
+      [Symbol.species]: { map: new Map<number, Ref<string>>() },
+      [Symbol.split]: new WeakSet<Ref<boolean>>(),
+      [Symbol.toPrimitive]: new WeakMap<Ref<boolean>, string>(),
+      [Symbol.toStringTag]: { weakSet: new WeakSet<Ref<boolean>>() },
+      [Symbol.unscopables]: { weakMap: new WeakMap<Ref<boolean>, 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', () => {

+ 3 - 32
packages/reactivity/src/ref.ts

@@ -274,36 +274,7 @@ type UnwrapRefSimple<T> = T extends
   : T extends Array<any>
   ? { [K in keyof T]: UnwrapRefSimple<T[K]> }
   : T extends object
-  ? UnwrappedObject<T>
+  ? {
+      [P in keyof T]: P extends symbol ? T[P] : UnwrapRef<T[P]>
+    }
   : 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 SymbolExtract<T> = (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 UnwrappedObject<T> = { [P in keyof T]: UnwrapRef<T[P]> } & SymbolExtract<T>

+ 32 - 6
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<Ref<number>>(),
+    [Symbol.matchAll]: new Map<number, Ref<string>>(),
+    [Symbol.replace]: { arr: [ref('a')] },
+    [Symbol.search]: { set: new Set<Ref<number>>() },
+    [Symbol.species]: { map: new Map<number, Ref<string>>() },
+    [Symbol.split]: new WeakSet<Ref<boolean>>(),
+    [Symbol.toPrimitive]: new WeakMap<Ref<boolean>, string>(),
+    [Symbol.toStringTag]: { weakSet: new WeakSet<Ref<boolean>>() },
+    [Symbol.unscopables]: { weakMap: new WeakMap<Ref<boolean>, 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<number> }>(objRef.value[customSymbol])
+  expectType<Ref<number>>(objRef.value[Symbol.asyncIterator])
+  expectType<{ a: Ref<string> }>(objRef.value[Symbol.hasInstance])
+  expectType<{ b: Ref<boolean> }>(objRef.value[Symbol.isConcatSpreadable])
+  expectType<Ref<number>[]>(objRef.value[Symbol.iterator])
+  expectType<Set<Ref<number>>>(objRef.value[Symbol.match])
+  expectType<Map<number, Ref<string>>>(objRef.value[Symbol.matchAll])
+  expectType<{ arr: Ref<string>[] }>(objRef.value[Symbol.replace])
+  expectType<{ set: Set<Ref<number>> }>(objRef.value[Symbol.search])
+  expectType<{ map: Map<number, Ref<string>> }>(objRef.value[Symbol.species])
+  expectType<WeakSet<Ref<boolean>>>(objRef.value[Symbol.split])
+  expectType<WeakMap<Ref<boolean>, string>>(objRef.value[Symbol.toPrimitive])
+  expectType<{ weakSet: WeakSet<Ref<boolean>> }>(
+    objRef.value[Symbol.toStringTag]
+  )
+  expectType<{ weakMap: WeakMap<Ref<boolean>, string> }>(
+    objRef.value[Symbol.unscopables]
+  )
+  expectType<{ arr: Ref<number>[] }>(objRef.value[customSymbol])
 }
 
 withSymbol()