From 3c1bd4efc6c69aebc9820f08b38cc09150ebfe76 Mon Sep 17 00:00:00 2001 From: Wu Rui Date: Wed, 30 Aug 2023 21:31:10 +0800 Subject: [PATCH] fix(components): [form] improve types (#14062) * fix(components): [form] improve types * docs: update form * fix: consider RegExp * chore: update jsdoc --- docs/en-US/component/form.md | 34 ++++++++++++++++++++++++++- packages/components/form/src/types.ts | 7 ++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/docs/en-US/component/form.md b/docs/en-US/component/form.md index 393469f87218a..72ead4a83ee3b 100644 --- a/docs/en-US/component/form.md +++ b/docs/en-US/component/form.md @@ -235,7 +235,39 @@ type FormValidateCallback = ( interface FormItemRule extends RuleItem { trigger?: Arrayable } -type FormRules = Partial>> + +type Primitive = null | undefined | string | number | boolean | symbol | bigint +type BrowserNativeObject = Date | FileList | File | Blob | RegExp +type IsTuple> = number extends T['length'] + ? false + : true +type ArrayMethodKey = keyof any[] +type TupleKey> = Exclude +type ArrayKey = number +type PathImpl = V extends + | Primitive + | BrowserNativeObject + ? `${K}` + : `${K}` | `${K}.${Path}` +type Path = T extends ReadonlyArray + ? IsTuple extends true + ? { + [K in TupleKey]-?: PathImpl, T[K]> + }[TupleKey] + : PathImpl + : { + [K in keyof T]-?: PathImpl, T[K]> + }[keyof T] +type FieldPath = T extends object ? Path : never +// MaybeRef: see [@vueuse/core](https://github.com/vueuse/vueuse/blob/main/packages/shared/utils/types.ts) +// UnwrapRef: see [vue](https://github.com/vuejs/core/blob/main/packages/reactivity/src/ref.ts) +type FormRules | string> = string> = + Partial< + Record< + UnwrapRef extends string ? UnwrapRef : FieldPath>, + Arrayable + > + > ``` diff --git a/packages/components/form/src/types.ts b/packages/components/form/src/types.ts index 99006f011c6d5..8a3383452696c 100644 --- a/packages/components/form/src/types.ts +++ b/packages/components/form/src/types.ts @@ -22,6 +22,7 @@ export interface FormItemRule extends RuleItem { } type Primitive = null | undefined | string | number | boolean | symbol | bigint +type BrowserNativeObject = Date | FileList | File | Blob | RegExp /** * Check whether it is tuple * @@ -60,7 +61,9 @@ type ArrayKey = number * * 用于通过一个类型递归构建路径的辅助类型 */ -type PathImpl = V extends Primitive +type PathImpl = V extends + | Primitive + | BrowserNativeObject ? `${K}` : `${K}` | `${K}.${Path}` /** @@ -85,7 +88,7 @@ type Path = T extends ReadonlyArray * 通过一个类型收集所有路径的类型 * * @example - * FieldPath<{ 1: number; a: number; b: string; c: { d: number; e: string }; f: [{ value: string }]; g: { value: string }[] }> => '1' | 'a' | 'b' | 'c' | 'f' | 'g' | 'c.d' | 'c.e' | 'f.0' | 'f.0.value' | 'g.number' | 'g.number.value' + * FieldPath<{ 1: number; a: number; b: string; c: { d: number; e: string }; f: [{ value: string }]; g: { value: string }[]; h: Date; i: FileList; j: File; k: Blob; l: RegExp }> => '1' | 'a' | 'b' | 'c' | 'f' | 'g' | 'c.d' | 'c.e' | 'f.0' | 'f.0.value' | 'g.number' | 'g.number.value' | 'h' | 'i' | 'j' | 'k' | 'l' */ type FieldPath = T extends object ? Path : never export type FormRules<