高扩展性类
最近在写ant design pro脚手架生成的ts项目,想把之前js版本的from表单区块升级成ts版本,遇到了一个问题,于是想记录下。
问题就是不同的表单提交项,JSON Schema内的需要传的值就不同。比如下拉选择就需要下拉选择的内容,日期选择就需要格式化后的格式等等。对于高扩展性的表单提交项,其JSON Schema对应的类也应该具有高拓展性。
Extract
ts官网是这么介绍的, 现在是Extract<keyof T, string>。(换句话说,是keyof T的子集,它仅包含类字符串的值。)。所以可以理解 在keyof T范围下满足第二个条件的一个子集。那么下面看看代码更改前后的变化。
before
import SearchSelect, { SearchInputProps } from './SearchSelect';
export interface listItem extends SearchInputProps, ChargeManagementListProps {
list?: any[];
name: string;
type: string;
span?: number;
label?: string;
required?: boolean | undefined;
message?: string;
mode?: "multiple" | "tags" | undefined;
initValue?: any;
maxLength?: number;
precision?: number;
selectArr?: selectItem[];
serverFormat?: string;
picker?: 'week' | 'month' | 'year' | undefined;
handleChange?: (props: any) => void;
[propName: string]: any;
}
export interface selectItem {
name: any;
value: number;
}
interface BaseFormProps {
type: number;
cancelFunc?: () => void;
okFunc?: (props: any) => void;
resetFunc?: () => void;
list?: listItem[];
}
listItem这个类只能加?来规避不同的提交项不同的传值,可以说写的不人性化。
after
type TypeProps = 'Text' | 'Select' | 'TextArea' | 'Group' | 'InputNumber' | 'Password' | 'SearchSelect' | 'DateRange' | 'ChargeManagementList';
type TextItem = {
type?: Extract<TypeProps, 'Text'>,
}
type SelectItem = {
type?: Extract<TypeProps, 'Select'>,
selectArr: selectItem[];
mode?: "multiple" | "tags" | undefined;
}
type TextAreaItem = {
type?: Extract<TypeProps, 'TextArea'>,
}
type GroupItem = {
type?: Extract<TypeProps, 'Group'>,
selectArr: selectItem[];
}
type InputNumberItem = {
type?: Extract<TypeProps, 'InputNumber'>,
}
type PasswordItem = {
type?: Extract<TypeProps, 'Password'>,
}
export type SearchSelectItem = {
type?: Extract<TypeProps, 'SearchSelect'>,
placeholder?: string;
style?: any;
getListApi: (props: any) => Promise<any>;
onChange?: (props: any) => void;
}
type DateRangePicekr = {
type?: Extract<TypeProps, 'DateRange'>,
picker: 'week' | 'month' | 'year';
}
export type ChargeManagementListItem = {
list: any[];
onChange?: (props: any) => void;
type?: Extract<TypeProps, 'ChargeManagementList'>,
}
type FormConfigItemProps = SelectItem | DateRangePicekr | TextItem | ChargeManagementListItem | SearchSelectItem | TextAreaItem | GroupItem | InputNumberItem | PasswordItem;
export type listItem = {
name: string;
span?: number;
label?: string;
required?: boolean | undefined;
message?: string;
initValue?: any;
maxLength?: number;
precision?: number;
serverFormat?: string;
handleChange?: (props: any) => void;
[propName: string]: any;
} & FormConfigItemProps;
export interface selectItem {
name: any;
value: number;
}
interface BaseFormProps {
type: number;
cancelFunc?: () => void;
okFunc?: (props: any) => void;
resetFunc?: () => void;
list?: listItem[];
}
改版后可以对所有不同的提交项目单独定制化处理,然后相应的组件的props的类也是可以直接引用这里的定义的item类。
-------------------2020.11.10 更新-----------------
以上方式就是typescript的联合类型。联合类型(Union Types)表示取值可以为多种类型中的一种。
例子如下:
interface Square {
kind: 'square';
size: number;
}
interface Rectangle {
kind: 'rectangle';
width: number;
height: number;
}
type Shape = Square | Rectangle;
function area(s: Shape) {
switch (s.kind) {
case: 'square':
return s.size * s.size;
case 'rectangle':
return s.width * s.height
}
}
总结就是联合类型可使类型具有一定的不确定性,提高代码的灵活性。