联合类型与透传契约 ​
这些代码块直接从当前源码导入,保持与包公开类型同源,不手写第二份 API 表。安装包中可从根入口导入对应公开类型;这里同时保留类型文件的依赖引用,完整解析由 TypeScript 负责。
AsamUpload ​
当前 docgen 对上传组件的交叉联合类型未能提取业务 Props、Events、Slots、Exposes。空表不表示没有接口。下面的源类型给出单选/多选值、函数/请求互斥、上传事件、插槽和 submit/cancel/clear 方法。
typescript
import type { UploadPropsPublic, UploadInstance, UploadFile, UploadUserFile } from 'element-plus';
import type { PublicProps } from 'vue';
import type { AsamControlSizeProps } from '../../control-size.js';
import type {
AsamDataError,
AsamUploadedResource,
AsamUploadFormData,
AsamUploadHandler,
AsamUploadRequestConfig
} from '../../data/types.js';
export type AsamUploadSource =
| { readonly upload: AsamUploadHandler; readonly request?: never }
| { readonly request: AsamUploadRequestConfig; readonly upload?: never };
export type AsamUploadValue = AsamUploadedResource | readonly AsamUploadedResource[] | null;
export type AsamResourceUploadProps = AsamUploadSource & {
readonly fieldName?: string;
readonly data?: AsamUploadFormData;
readonly accept?: string;
readonly drag?: boolean;
readonly maxSizeBytes?: number;
readonly limit?: number;
readonly autoUpload?: boolean;
readonly disabled?: boolean;
readonly validate?: (file: File) => boolean | string;
} & (
| { readonly multiple?: false; readonly modelValue: AsamUploadedResource | null }
| { readonly multiple: true; readonly modelValue: readonly AsamUploadedResource[] }
);
export interface AsamUploadItem {
readonly clientId: string;
readonly name: string;
readonly mimeType: string;
readonly size: number;
readonly status: 'ready' | 'uploading' | 'success' | 'error' | 'cancelled';
readonly percent?: number;
readonly resource?: AsamUploadedResource;
readonly error?: AsamDataError;
}
export interface AsamUploadEmits {
'update:modelValue': [value: AsamUploadValue];
'update:fileList': [value: UploadUserFile[]];
change: [value: AsamUploadValue];
progress: [item: AsamUploadItem];
success: [resource: AsamUploadedResource, item: AsamUploadItem];
error: [error: AsamDataError, item: AsamUploadItem];
cancelled: [item: AsamUploadItem];
remove: [resource: AsamUploadedResource];
}
export interface AsamResourceUploadExpose {
submit(): void;
cancel(clientId?: string): void;
clear(): void;
}
/** Resource-mode slots. Native mode uses AsamNativeUploadSlots without resource actions. */
export interface AsamUploadSlots {
default?: () => unknown;
trigger?: () => unknown;
tip?: () => unknown;
file?: (scope: {
file: UploadFile;
index: number;
item: AsamUploadItem;
remove: () => void;
cancel: () => void;
}) => unknown;
}
/** Native file slot is exactly the dependency slot; resource actions belong to resource mode. */
export type AsamNativeUploadSlots = UploadInstance['$slots'];
/** Raw Element Plus file-list mode has no ASAM transport/resource source. */
export type AsamNativeUploadProps = UploadPropsPublic &
AsamControlSizeProps & {
readonly mode: 'native';
readonly upload?: never;
readonly request?: never;
readonly modelValue?: never;
readonly fieldName?: never;
readonly maxSizeBytes?: never;
readonly validate?: never;
};
export type AsamUploadProps =
| AsamNativeUploadProps
| (AsamResourceUploadProps & AsamControlSizeProps & { readonly mode?: 'resource' });
export type AsamNativeUploadExpose = Pick<
UploadInstance,
'abort' | 'submit' | 'clearFiles' | 'handleStart' | 'handleRemove'
>;
export type AsamUploadExpose = AsamNativeUploadExpose & AsamResourceUploadExpose;
type AsamUploadMode = 'native' | 'resource';
type AsamUploadModeEvents<M extends AsamUploadMode> = M extends 'native'
? Pick<AsamUploadEmits, 'update:fileList'>
: AsamUploadEmits;
type AsamUploadModeListeners<M extends AsamUploadMode> = {
[K in keyof AsamUploadModeEvents<M> & string as `on${Capitalize<K>}`]?: (
...args: AsamUploadModeEvents<M>[K] extends unknown[] ? AsamUploadModeEvents<M>[K] : never
) => void;
};
// Distribute complete bindings so InstanceType retains each mode's own listeners.
type AsamUploadModeBindings<M extends AsamUploadMode> = M extends 'native'
? AsamNativeUploadProps & AsamUploadModeListeners<M> & PublicProps
: Extract<AsamUploadProps, { readonly mode?: 'resource' }> &
AsamUploadModeListeners<M> &
PublicProps;
/**
* Preserve metadata while inferring each mode's own props, listeners, slots and expose.
* Native hooks remain the original UploadPropsPublic functions; resource events retain ASAM tuples.
* The constructor takes props so Vue's template checker can contextualize inline handlers from mode.
*/
export type AsamUploadModeComponent<C extends abstract new (...args: never[]) => unknown> = Omit<
C,
never
> & {
new <M extends AsamUploadMode = 'resource'>(
props?: { readonly mode?: M } & AsamUploadModeBindings<NoInfer<M>>
): Omit<InstanceType<C>, '$props' | '$slots'> & {
$props: AsamUploadModeBindings<M>;
$slots: M extends 'native' ? AsamNativeUploadSlots : AsamUploadSlots;
};
};
远程与字典单选、多选 ​
AsamRemoteRadio、AsamDictRadio、AsamRemoteCheckbox、AsamDictCheckbox 是通过 $attrs 转发的薄包装,docgen 无法从包装 SFC 自动枚举实际属性与事件。对应 Props 与 AsamAsyncChoiceExpose 见同源类型;更新值和 change 事件沿用基础 AsamRadio / AsamCheckbox,reload、cancel 为远程包装暴露的方法。控件不提供未声明的插槽。
typescript
import type { CheckboxGroupPropsPublic, RadioGroupPropsPublic } from 'element-plus';
import type { AsamControlSizeProps } from '../../control-size.js';
import type { AsamOption, AsamRecord, AsamValue } from '../../data/types.js';
import type { AsamSelectionComponent } from '../AsamSelect/PublicComponent.js';
import type { UnsupportedStaticChoiceSourceProp } from './StaticSourceAttrs.js';
export type AsamChoiceOption<
V extends AsamValue = AsamValue,
I extends object = AsamRecord
> = AsamOption<V, I>;
export type AsamRadioModelValue<
V extends AsamValue,
I extends object,
M extends 'value' | 'object'
> = M extends 'object' ? AsamChoiceOption<V, I> | null : V | null;
export type AsamCheckboxModelValue<
V extends AsamValue,
I extends object,
M extends 'value' | 'object',
S extends 'array' | 'string'
> = S extends 'string'
? string
: M extends 'object'
? readonly AsamChoiceOption<V, I>[]
: readonly V[];
interface ChoiceOptions<V extends AsamValue, I extends object> extends AsamControlSizeProps {
readonly options?: readonly AsamChoiceOption<V, I>[];
readonly disabled?: boolean;
readonly name?: string;
readonly id?: string;
readonly validateEvent?: boolean;
}
/** Options + Group aggregate. Raw native inputs use the separate Item/Group/Button entries. */
export type AsamRadioProps<
V extends AsamValue = AsamValue,
I extends object = AsamRecord
> = ChoiceOptions<V, I> &
Omit<RadioGroupPropsPublic, 'modelValue' | 'options' | 'type' | 'props' | 'size'> & {
type?: 'radio' | 'button';
} & (
| { readonly modelValue?: V | null; readonly valueMode?: 'value' }
| { readonly modelValue?: AsamChoiceOption<V, I> | null; readonly valueMode: 'object' }
);
/** Options + Group aggregate with ASAM object and string storage policies. */
export type AsamCheckboxProps<
V extends AsamValue = AsamValue,
I extends object = AsamRecord
> = ChoiceOptions<V, I> &
Omit<CheckboxGroupPropsPublic, 'modelValue' | 'options' | 'type' | 'props' | 'size'> & {
type?: 'checkbox' | 'button';
} & (
| {
readonly modelValue?: readonly V[];
readonly valueMode?: 'value';
readonly multipleValueMode?: 'array';
readonly separator?: never;
}
| {
readonly modelValue?: string;
readonly valueMode?: 'value';
readonly multipleValueMode: 'string';
readonly separator?: string;
}
| {
readonly modelValue?: readonly AsamChoiceOption<V, I>[];
readonly valueMode: 'object';
readonly multipleValueMode?: 'array';
readonly separator?: never;
}
);
export interface AsamChoiceRuntimeProps
extends
Omit<
CheckboxGroupPropsPublic,
| 'modelValue'
| 'options'
| 'type'
| 'props'
| 'size'
| 'disabled'
| 'name'
| 'id'
| 'validateEvent'
| 'valueMode'
| 'multipleValueMode'
| 'separator'
>,
AsamControlSizeProps {
// Keep the runtime prop uncast so Vue preserves omitted and explicit null values.
readonly modelValue?: unknown;
readonly options?: readonly AsamChoiceOption<AsamValue, object>[];
readonly disabled?: boolean;
readonly name?: string;
readonly id?: string;
readonly validateEvent?: boolean;
readonly valueMode?: 'value' | 'object';
readonly multipleValueMode?: 'array' | 'string';
readonly separator?: string;
}
/** Transitional type exports; data implementations own DataTypes.ts. */
export type {
AsamRemoteRadioProps,
AsamRemoteCheckboxProps,
AsamDictRadioProps,
AsamDictCheckboxProps,
AsamAsyncChoiceExpose
} from './DataTypes.js';
/** Native Group handles raw option-field mapping; the ASAM composite keeps normalized options. */
export interface AsamRadioSlots {
default?: () => unknown;
option?: (scope: { option: AsamChoiceOption<AsamValue, object> }) => unknown;
}
export type AsamCheckboxSlots = AsamRadioSlots;
export type AsamRadioPublicComponent = AsamSelectionComponent<
AsamRadioProps<AsamValue, object>,
{
'update:modelValue': [value: AsamRadioModelValue<AsamValue, object, 'value' | 'object'>];
change: [value: AsamRadioModelValue<AsamValue, object, 'value' | 'object'>];
},
AsamRadioSlots,
Record<string, never>,
false,
| UnsupportedStaticChoiceSourceProp
| 'props'
| 'min'
| 'max'
| 'tag'
| 'multipleValueMode'
| 'separator'
>;
export type AsamCheckboxPublicComponent = AsamSelectionComponent<
AsamCheckboxProps<AsamValue, object>,
{
'update:modelValue': [
value: AsamCheckboxModelValue<AsamValue, object, 'value' | 'object', 'array' | 'string'>
];
change: [
value: AsamCheckboxModelValue<AsamValue, object, 'value' | 'object', 'array' | 'string'>
];
},
AsamCheckboxSlots,
Record<string, never>,
true,
UnsupportedStaticChoiceSourceProp | 'props'
>;
其他联合类型、透传属性和泛型字段的边界,见各组件 Docs 页的类型入口。自动文档不替代包消费类型检查;可运行示例仍在 已列组件目录 的组件入口。