fix: 函数式 componentProps 按已注册 component 的 Props 校验返回值

This commit is contained in:
dullathanol
2026-04-03 13:36:03 +08:00
committed by allen
parent 794b103aa9
commit 5ed39c03a4
6 changed files with 102 additions and 48 deletions

View File

@@ -32,19 +32,28 @@ import type {
import type { ComponentType } from './component'; import type { ComponentType } from './component';
type ComponentPropsFnArgs = Parameters<
Extract<
NonNullable<CoreFormSchema<ComponentType>['componentProps']>,
(...args: any) => any
>
>;
/** /**
* 对象形式:使用适配器里为各 `component` 声明的 Props 类型 `P` * 使用适配器里为各 `component` 声明的 Props 类型 `P`
* 与 `Record<string, any>` 相交是为了满足核心库 `MaybeComponentProps` 的索引签名。 * 与 `Record<string, any>` 相交以兼容核心库 `MaybeComponentProps` 的索引签名。
* 函数形式:通过联合 `CoreFormSchema['componentProps']`,与表单核心对动态 `componentProps` 的约定保持一致。
*/ */
type SchemaComponentProps<P> = type ComponentProps<P> =
| CoreFormSchema<ComponentType>['componentProps'] | ((
value: ComponentPropsFnArgs[0],
actions: ComponentPropsFnArgs[1],
) => P & Record<string, any>)
| (P & Record<string, any>); | (P & Record<string, any>);
/** /**
* 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示 * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
*/ */
interface FormSchemaComponentPropsMap { interface ComponentPropsMap {
ApiCascader: ApiComponentSharedProps & CascaderProps; ApiCascader: ApiComponentSharedProps & CascaderProps;
ApiSelect: ApiComponentSharedProps & SelectProps; ApiSelect: ApiComponentSharedProps & SelectProps;
ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps; ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
@@ -79,12 +88,12 @@ type BaseSchema = Omit<
'component' | 'componentProps' 'component' | 'componentProps'
>; >;
type RegisteredName = keyof FormSchemaComponentPropsMap; type RegisteredName = keyof ComponentPropsMap;
type DiscriminatedFormSchema = { type DiscriminatedFormSchema = {
[K in RegisteredName]: BaseSchema & { [K in RegisteredName]: BaseSchema & {
component: K; component: K;
componentProps?: SchemaComponentProps<FormSchemaComponentPropsMap[K]>; componentProps?: ComponentProps<ComponentPropsMap[K]>;
}; };
}[RegisteredName]; }[RegisteredName];

View File

@@ -32,19 +32,28 @@ import type {
import type { ComponentType } from './component'; import type { ComponentType } from './component';
type ComponentPropsFnArgs = Parameters<
Extract<
NonNullable<CoreFormSchema<ComponentType>['componentProps']>,
(...args: any) => any
>
>;
/** /**
* 对象形式:使用适配器里为各 `component` 声明的 Props 类型 `P` * 使用适配器里为各 `component` 声明的 Props 类型 `P`
* 与 `Record<string, any>` 相交是为了满足核心库 `MaybeComponentProps` 的索引签名。 * 与 `Record<string, any>` 相交以兼容核心库 `MaybeComponentProps` 的索引签名。
* 函数形式:通过联合 `CoreFormSchema['componentProps']`,与表单核心对动态 `componentProps` 的约定保持一致。
*/ */
type SchemaComponentProps<P> = type ComponentProps<P> =
| CoreFormSchema<ComponentType>['componentProps'] | ((
value: ComponentPropsFnArgs[0],
actions: ComponentPropsFnArgs[1],
) => P & Record<string, any>)
| (P & Record<string, any>); | (P & Record<string, any>);
/** /**
* 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示 * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
*/ */
interface FormSchemaComponentPropsMap { interface ComponentPropsMap {
ApiCascader: ApiComponentSharedProps & CascaderProps; ApiCascader: ApiComponentSharedProps & CascaderProps;
ApiSelect: ApiComponentSharedProps & SelectProps; ApiSelect: ApiComponentSharedProps & SelectProps;
ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps; ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
@@ -79,12 +88,12 @@ type BaseSchema = Omit<
'component' | 'componentProps' 'component' | 'componentProps'
>; >;
type RegisteredName = keyof FormSchemaComponentPropsMap; type RegisteredName = keyof ComponentPropsMap;
type DiscriminatedFormSchema = { type DiscriminatedFormSchema = {
[K in RegisteredName]: BaseSchema & { [K in RegisteredName]: BaseSchema & {
component: K; component: K;
componentProps?: SchemaComponentProps<FormSchemaComponentPropsMap[K]>; componentProps?: ComponentProps<ComponentPropsMap[K]>;
}; };
}[RegisteredName]; }[RegisteredName];

View File

@@ -27,19 +27,28 @@ import type { ComponentType } from './component';
type ElTreeSelectSchemaProps = InstanceType<typeof ElTreeSelect>['$props']; type ElTreeSelectSchemaProps = InstanceType<typeof ElTreeSelect>['$props'];
type ElTimePickerSchemaProps = InstanceType<typeof ElTimePicker>['$props']; type ElTimePickerSchemaProps = InstanceType<typeof ElTimePicker>['$props'];
type ComponentPropsFnArgs = Parameters<
Extract<
NonNullable<CoreFormSchema<ComponentType>['componentProps']>,
(...args: any) => any
>
>;
/** /**
* 对象形式:使用适配器里为各 `component` 声明的 Props 类型 `P` * 使用适配器里为各 `component` 声明的 Props 类型 `P`
* 与 `Record<string, any>` 相交是为了满足核心库 `MaybeComponentProps` 的索引签名。 * 与 `Record<string, any>` 相交以兼容核心库 `MaybeComponentProps` 的索引签名。
* 函数形式:通过联合 `CoreFormSchema['componentProps']`,与表单核心对动态 `componentProps` 的约定保持一致。
*/ */
type SchemaComponentProps<P> = type ComponentProps<P> =
| CoreFormSchema<ComponentType>['componentProps'] | ((
value: ComponentPropsFnArgs[0],
actions: ComponentPropsFnArgs[1],
) => P & Record<string, any>)
| (P & Record<string, any>); | (P & Record<string, any>);
/** /**
* 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示 * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
*/ */
interface FormSchemaComponentPropsMap { interface ComponentPropsMap {
ApiSelect: ApiComponentSharedProps & SelectV2Props; ApiSelect: ApiComponentSharedProps & SelectV2Props;
ApiTreeSelect: ApiComponentSharedProps & ElTreeSelectSchemaProps; ApiTreeSelect: ApiComponentSharedProps & ElTreeSelectSchemaProps;
Checkbox: CheckboxProps; Checkbox: CheckboxProps;
@@ -63,12 +72,12 @@ type BaseSchema = Omit<
'component' | 'componentProps' 'component' | 'componentProps'
>; >;
type RegisteredName = keyof FormSchemaComponentPropsMap; type RegisteredName = keyof ComponentPropsMap;
type DiscriminatedFormSchema = { type DiscriminatedFormSchema = {
[K in RegisteredName]: BaseSchema & { [K in RegisteredName]: BaseSchema & {
component: K; component: K;
componentProps?: SchemaComponentProps<FormSchemaComponentPropsMap[K]>; componentProps?: ComponentProps<ComponentPropsMap[K]>;
}; };
}[RegisteredName]; }[RegisteredName];

View File

@@ -24,19 +24,28 @@ import type {
import type { ComponentType } from './component'; import type { ComponentType } from './component';
type ComponentPropsFnArgs = Parameters<
Extract<
NonNullable<CoreFormSchema<ComponentType>['componentProps']>,
(...args: any) => any
>
>;
/** /**
* 对象形式:使用适配器里为各 `component` 声明的 Props 类型 `P` * 使用适配器里为各 `component` 声明的 Props 类型 `P`
* 与 `Record<string, any>` 相交是为了满足核心库 `MaybeComponentProps` 的索引签名。 * 与 `Record<string, any>` 相交以兼容核心库 `MaybeComponentProps` 的索引签名。
* 函数形式:通过联合 `CoreFormSchema['componentProps']`,与表单核心对动态 `componentProps` 的约定保持一致。
*/ */
type SchemaComponentProps<P> = type ComponentProps<P> =
| CoreFormSchema<ComponentType>['componentProps'] | ((
value: ComponentPropsFnArgs[0],
actions: ComponentPropsFnArgs[1],
) => P & Record<string, any>)
| (P & Record<string, any>); | (P & Record<string, any>);
/** /**
* 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示 * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
*/ */
interface FormSchemaComponentPropsMap { interface ComponentPropsMap {
ApiSelect: ApiComponentSharedProps & SelectProps; ApiSelect: ApiComponentSharedProps & SelectProps;
ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps; ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
Checkbox: CheckboxProps; Checkbox: CheckboxProps;
@@ -60,12 +69,12 @@ type BaseSchema = Omit<
'component' | 'componentProps' 'component' | 'componentProps'
>; >;
type RegisteredName = keyof FormSchemaComponentPropsMap; type RegisteredName = keyof ComponentPropsMap;
type DiscriminatedFormSchema = { type DiscriminatedFormSchema = {
[K in RegisteredName]: BaseSchema & { [K in RegisteredName]: BaseSchema & {
component: K; component: K;
componentProps?: SchemaComponentProps<FormSchemaComponentPropsMap[K]>; componentProps?: ComponentProps<ComponentPropsMap[K]>;
}; };
}[RegisteredName]; }[RegisteredName];

View File

@@ -30,19 +30,28 @@ import type {
import type { ComponentType } from './component'; import type { ComponentType } from './component';
type ComponentPropsFnArgs = Parameters<
Extract<
NonNullable<CoreFormSchema<ComponentType>['componentProps']>,
(...args: any) => any
>
>;
/** /**
* 对象形式:使用适配器里为各 `component` 声明的 Props 类型 `P` * 使用适配器里为各 `component` 声明的 Props 类型 `P`
* 与 `Record<string, any>` 相交是为了满足核心库 `MaybeComponentProps` 的索引签名。 * 与 `Record<string, any>` 相交以兼容核心库 `MaybeComponentProps` 的索引签名。
* 函数形式:通过联合 `CoreFormSchema['componentProps']`,与表单核心对动态 `componentProps` 的约定保持一致。
*/ */
type SchemaComponentProps<P> = type ComponentProps<P> =
| CoreFormSchema<ComponentType>['componentProps'] | ((
value: ComponentPropsFnArgs[0],
actions: ComponentPropsFnArgs[1],
) => P & Record<string, any>)
| (P & Record<string, any>); | (P & Record<string, any>);
/** /**
* 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示 * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
*/ */
interface FormSchemaComponentPropsMap { interface ComponentPropsMap {
ApiSelect: ApiComponentSharedProps & SelectProps; ApiSelect: ApiComponentSharedProps & SelectProps;
ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps; ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
AutoComplete: AutoCompleteProps; AutoComplete: AutoCompleteProps;
@@ -73,12 +82,12 @@ type BaseSchema = Omit<
'component' | 'componentProps' 'component' | 'componentProps'
>; >;
type RegisteredName = keyof FormSchemaComponentPropsMap; type RegisteredName = keyof ComponentPropsMap;
type DiscriminatedFormSchema = { type DiscriminatedFormSchema = {
[K in RegisteredName]: BaseSchema & { [K in RegisteredName]: BaseSchema & {
component: K; component: K;
componentProps?: SchemaComponentProps<FormSchemaComponentPropsMap[K]>; componentProps?: ComponentProps<ComponentPropsMap[K]>;
}; };
}[RegisteredName]; }[RegisteredName];

View File

@@ -32,19 +32,28 @@ import type {
import type { ComponentType } from './component'; import type { ComponentType } from './component';
type ComponentPropsFnArgs = Parameters<
Extract<
NonNullable<CoreFormSchema<ComponentType>['componentProps']>,
(...args: any) => any
>
>;
/** /**
* 对象形式:使用适配器里为各 `component` 声明的 Props 类型 `P` * 使用适配器里为各 `component` 声明的 Props 类型 `P`
* 与 `Record<string, any>` 相交是为了满足核心库 `MaybeComponentProps` 的索引签名。 * 与 `Record<string, any>` 相交以兼容核心库 `MaybeComponentProps` 的索引签名。
* 函数形式:通过联合 `CoreFormSchema['componentProps']`,与表单核心对动态 `componentProps` 的约定保持一致。
*/ */
type SchemaComponentProps<P> = type ComponentProps<P> =
| CoreFormSchema<ComponentType>['componentProps'] | ((
value: ComponentPropsFnArgs[0],
actions: ComponentPropsFnArgs[1],
) => P & Record<string, any>)
| (P & Record<string, any>); | (P & Record<string, any>);
/** /**
* 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示 * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
*/ */
interface FormSchemaComponentPropsMap { interface ComponentPropsMap {
ApiCascader: ApiComponentSharedProps & CascaderProps; ApiCascader: ApiComponentSharedProps & CascaderProps;
ApiSelect: ApiComponentSharedProps & SelectProps; ApiSelect: ApiComponentSharedProps & SelectProps;
ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps; ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
@@ -79,12 +88,12 @@ type BaseSchema = Omit<
'component' | 'componentProps' 'component' | 'componentProps'
>; >;
type RegisteredName = keyof FormSchemaComponentPropsMap; type RegisteredName = keyof ComponentPropsMap;
type DiscriminatedFormSchema = { type DiscriminatedFormSchema = {
[K in RegisteredName]: BaseSchema & { [K in RegisteredName]: BaseSchema & {
component: K; component: K;
componentProps?: SchemaComponentProps<FormSchemaComponentPropsMap[K]>; componentProps?: ComponentProps<ComponentPropsMap[K]>;
}; };
}[RegisteredName]; }[RegisteredName];