Просмотр исходного кода

fix(types): should unwrap array -> object -> ref

Evan You 5 лет назад
Родитель
Сommit
82b28a5ecb
3 измененных файлов с 21 добавлено и 3 удалено
  1. 1 1
      .eslintrc.js
  2. 3 2
      packages/reactivity/src/ref.ts
  3. 17 0
      test-dts/ref.test-d.ts

+ 1 - 1
.eslintrc.js

@@ -26,7 +26,7 @@ module.exports = {
   overrides: [
     // tests, no restrictions (runs in Node / jest with jsdom)
     {
-      files: ['**/__tests__/**'],
+      files: ['**/__tests__/**', 'test-dts/**'],
       rules: {
         'no-restricted-globals': 'off',
         'no-restricted-syntax': 'off'

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

@@ -165,10 +165,11 @@ type UnwrapRefSimple<T> = T extends
   | CollectionTypes
   | BaseTypes
   | Ref
-  | Array<any>
   | RefUnwrapBailTypes[keyof RefUnwrapBailTypes]
   ? T
-  : T extends object ? UnwrappedObject<T> : T
+  : T extends Array<any>
+    ? { [K in keyof T]: T[K] extends Ref ? T[K] : UnwrapRefSimple<T[K]> }
+    : T extends object ? UnwrappedObject<T> : T
 
 // Extract all known symbols from an object
 // when unwrapping Object the symbols are not `in keyof`, this should cover all the

+ 17 - 0
test-dts/ref.test-d.ts

@@ -41,6 +41,23 @@ function plainType(arg: number | Ref<number>) {
   expectType<Ref<IteratorFoo | null | undefined>>(
     ref<IteratorFoo | null | undefined>()
   )
+
+  // should not unwrap ref inside arrays
+  const arr = ref([1, new Map<string, any>(), ref('1')]).value
+  const value = arr[0]
+  if (isRef(value)) {
+    expectType<Ref>(value)
+  } else if (typeof value === 'number') {
+    expectType<number>(value)
+  } else {
+    // should narrow down to Map type
+    // and not contain any Ref type
+    expectType<Map<string, any>>(value)
+  }
+
+  // should still unwrap in objects nested in arrays
+  const arr2 = ref([{ a: ref(1) }]).value
+  expectType<number>(arr2[0].a)
 }
 
 plainType(1)