什么是类型联动呢? 假如有如下类型
tstype Component = {
type: 'button' | 'input' | 'select' | 'textarea';
payload: {
onChange: Function;
onClick: Function;
type: string;
placeholder: string;
};
}
类型联动,指的是当 type 的值发生变化时,payload的类型也跟着变化,比如当type为’input’时,可能希望payload中包含onChange,而当type为’button’时,则不希望payload中包含onChange。
业务需求如下: 封装动态表单组件,渲染表单类型和各自的配置项通过prop传递进去。方便在编写表单项配置时,让ts提供类型提示功能,比如当type值为Select时,对应的事件有ngModelChange、nzOpenChange;当type值为CheckBox时,对应的事件有ngModelChange
ts
// Select对应的事件
interface SelectEvent {
ngModelChange?: (e: any) => void;
nzOpenChange?: (val:boolean) => void
}
// CheckBox对应的事件
interface CheckBoxEvent {
ngModelChange: (e: any) => void;
}
interface Events {
Select: SelectEvent;
CheckBox: CheckBoxEvent;
}
type FormType = keyof Events;
// => 'Select' | 'CheckBox'
type EventType = {
[T in keyof Events]: {
type: T
events: Events[T];
};
}[keyof Events];
// => {type: "Select";events: SelectEvent;} | {type: "CheckBox";events: CheckBoxEvent;}
type FormItemWrap = {
filed: string; // filed
label: string; // label
value: any; // value
hidden: boolean; //是否隐藏
required: boolean; // 是否必填
placeholder?: string;
//type: FormType;
} & EventType;


业务升级,每个表单项组件除了事件配置不同,还有各自的配置参数
ts
interface SelectEvent {
ngModelChange?: (...args:any[]) => void;
nzOpenChange?: (...args:any[]) => void
}
interface CheckBoxEvent {
ngModelChange?: (e: any) => void;
}
// 表单组件独有配置项映射关系
type CompMapping = {
Select: {
events: SelectEvent;
nzAllowClear?: boolean;
data: {label:string,value:any,[prop:string]:any}[]
};
Checkbox: {
events: CheckBoxEvent
}
};
type FormComp = {
[T in keyof CompMapping]: {
type: T;
} & CompMapping[T];
}[keyof CompMapping];
// 表单项通用部分
type FormBase = {
filed: string; // filed
label: string; // label
value: any; // value
hidden?: boolean; //是否隐藏
required?: boolean; // 是否必填
placeholder?: string;
};
type FormItem = FormBase & FormComp
const select:FormItem = {
type: "Select",
filed:"hobby",
label: "爱好",
value: [],
data: [{ checked: false, label: "绘画", value: '1' }, { label: "唱歌", value: '2' }],
events: {
ngModelChange(e) {
console.log(e);
},
}
}


本文作者:千寻
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!