瀏覽代碼

fix: add Reg/Map/Set endpoint

point.halo 10 月之前
父節點
當前提交
7fc80dfa0b
共有 2 個文件被更改,包括 37 次插入53 次删除
  1. 31 52
      packages/semi-foundation/form/interface.ts
  2. 6 1
      packages/semi-ui/form/_story/form.stories.tsx

+ 31 - 52
packages/semi-foundation/form/interface.ts

@@ -51,49 +51,6 @@ type ArrayIndexPath<K extends string | number, U> =
     | `${K}.${number}`  // 支持 array.index
     | `${K}.${number}.${FieldPath<U>}`; // 支持 array.index.child
 
-// FieldPath 类型定义,支持对象和数组字段路径
-// export type FieldPath<T> = T extends Array<infer U>
-//     ? | `${number}`                      // 如果是数组,支持数字索引(如 `[0]`)
-//     | `${number}.${FieldPath<U>}`      // 支持数组嵌套路径(如 `[0].field`)
-//     : T extends object
-//         ? {
-//             [K in keyof T]: K extends string
-//                 ? T[K] extends Array<infer U> | object
-//                     ? | `${K}` 
-//                     | `${K}.${FieldPath<T[K]>}`
-//                     | ArrayIndexPath<K, U>
-//                     : `${K}`                            // 只允许键路径
-//                 : never;
-//         }[keyof T]
-//         : never;
-
-// FieldPath 类型定义,支持对象和数组字段路径
-export type FieldPath<T> = T extends Array<infer U>
-    ? `${number}` | `${number}.${FieldPath<Exclude<U, undefined>>}`
-    : T extends object ? {
-        [K in keyof T]: K extends string
-            ? Exclude<T[K], undefined> extends Date
-                ? `${K}`
-                : T[K] extends Array<infer U> | object | undefined
-                    ? `${K}` |
-              `${K}.${FieldPath<T[K]>}` |
-                ArrayIndexPath<K, U>
-                    : `${K}`
-            : never;
-    }[keyof T]
-        : never;
-
-        
-export type FieldPathValue<T, P extends string> =
-  ArrayFieldPathValue<T, P> |
-  (P extends `${infer K}.${infer Rest}`
-      ? K extends keyof T
-          ? FieldPathValue<Exclude<T[K], undefined>, Rest>   // 添加 undefined过滤,避免用户 tsconfig strictNullChecks 为 true 时,无法正确推断
-          : never
-      : P extends keyof T
-          ? T[P]
-          : never);
-
 type ArrayFieldPathValue<T, P extends string> =
     P extends `${infer K}[${infer I}]${infer Rest}`
         ? K extends keyof T
@@ -109,16 +66,38 @@ type ArrayFieldPathValue<T, P extends string> =
             : never
         : never;
 
+// 判断是否是特殊类型(如 Date、Set、Map、RegExp 等, 无需继续推导)
+type IsSpecialObject<T> =
+  T extends Date | RegExp | Map<any, any> | Set<any>
+      ? true
+      : false;
+
+// FieldPath 类型定义,支持对象和数组字段路径,支持数字索引(如 `[0]`),支持数组嵌套路径(如 `[0].field`)
+export type FieldPath<T> = T extends Array<infer U>
+    ? `${number}` | `${number}.${FieldPath<NonNullable<U>>}` 
+    : T extends object
+        ? {
+            [K in keyof T]: K extends string
+            // ? Exclude<T[K], undefined> extends Date
+                ? IsSpecialObject<NonNullable<T[K]>> extends true
+                    ? `${K}` // 如果是特殊类型(如 Date、Set 等),只允许顶层键路径
+                    : T[K] extends Array<infer U> | object | undefined
+                        ? `${K}` | `${K}.${FieldPath<Required<T[K]>>}` |ArrayIndexPath<K, U> // 嵌套处理
+                        : `${K}`
+                : never;
+        }[keyof T]
+        : never;
+
 // FieldPathValue 类型定义,支持从路径字符串中推导数组和对象的值
-// export type FieldPathValue<T, P extends string> =
-//     ArrayFieldPathValue<T, P> // 处理数组路径
-//     | (P extends `${infer K}.${infer Rest}`
-//         ? K extends keyof T
-//             ? FieldPathValue<Exclude<T[K], undefined>, Rest> // 添加 undefined过滤,避免用户 tsconfig strictNullChecks 为 true 时,无法正确推断
-//             : never
-//         : P extends keyof T
-//             ? T[P]
-//             : never);
+export type FieldPathValue<T, P extends string> =
+  ArrayFieldPathValue<T, P> |
+  (P extends `${infer K}.${infer Rest}`
+      ? K extends keyof T
+          ? FieldPathValue<NonNullable<T[K]>, Rest>   // 添加 undefined过滤,避免用户 tsconfig strictNullChecks 为 true 时,无法正确推断
+          : never
+      : P extends keyof T
+          ? T[P]
+          : never);
 
 // use object replace Record<string, any>, fix issue 933
 export interface BaseFormApi<FormValuesType extends object = any> {

+ 6 - 1
packages/semi-ui/form/_story/form.stories.tsx

@@ -145,7 +145,9 @@ interface FData {
                         R32: number;
                         R33: boolean;
                     }>;
-                }
+                },
+                testS: Set<string>;
+                testT: Map<string, number>;
             }
         };
     };
@@ -158,6 +160,9 @@ const FCDemo = () => {
     let year = testO?.getFullYear();
     let testP = formApi.getValue('optional.testM.testN.testP');
     testP = testP + 1;
+    let testSet = formApi.getValue('optional.testM.testN.testS');
+    let testMap = formApi.getValue('optional.testM.testN.testT');
+
     let NotExist = formApi.getValue('optional.testM.testN.NotExist');
 
     // ✅ 应该合法的, 注意,setValue只对 fieldPath做校验,对 value 不做严格校验