1. interface使用技巧
1.1 可选属性
interface IPersonAttr {
id: string;
name: string;
favourite?: string | string[];
}
要实现IPersonAttr这个接口的对象:
- 要有类型为
string的id属性和类型为string的name属性 favourite属性若有,则为string或者string[]类型favourite属性若无,则为undefined
1.2 继承
interface IStudentAttr extends IPersonAttr {
level: number;
}
要实现IStudentAttr这个接口的对象:
- 要有类型为
string的id属性和类型为string的name属性 - 要有类型为
number的level属性 - 可以继承多个,以逗号隔开
interface IStudentAttr extends IPersonAttr {
id: number; // Type 'number' is not assignable to type 'string'
level: number;
}
- 继承时,无法实现覆盖,会报错
- 可以尝试使用
Omit<T,K>,这样生成的IStudentAttr的id就是number类型了
interface IStudentAttr extends Omit<IPersonAttr, 'id'> {
id: number;
level: number;
}
1.3 泛型
interface IAccountAttr<T = any> {
user: T;
account: number;
}
const lawsonAccount: IAccountAttr<IStudentAttr> = {
user: {
id: 123,
name: 'lawson',
level: 3,
},
account: 100,
};
- 实例化时,传递啥类型,内部类型就是啥类型
1.4 可扩展
interface IAccountAttr<T = any> {
user: T;
account: number;
[prop: string]: any; // 扩展属性
}
const lawsonAccount: IAccountAttr<IStudentAttr> = {
user: {
id: 123,
name: 'lawson',
level: 3,
},
account: 100,
age: 18,
};
- 可以让
IAccountAttr接收额外的属性 - 不便于检查额外属性类型
2 type
2.1 可选属性
type IPersonAttr = {
id: string;
name: string;
favourite?: string[];
}
2.2 继承
type IStudentAttr = Omit<IPersonAttr, 'id'> & { id: number; level: number };
2.3 罗列
type IDivision = 'liberal arts' | 'science' | 'engineering';
type IPersonAttrKey = keyof IPersonAttr; // 等价于type IPersonAttrKey ='id' | 'name' | 'favourite'
keyof可以获取一个对象、接口的所有key,并罗列
2.3 范围
type IDivisionStudentAttr = {
[prop in IDivision]: IStudentAttr;
};
- 对象要实现所有的
IDivision接口属性作为key值的可能性
3. enum使用技巧
3.1 对类型的约束
// 表单项的组件类型,即要有formSettings下的name
export enum FormItemTypeEnum {
INPUT = 'input', // 文本输入框
INPUTNUMBER = 'inputNumber', // 数值输入框
...
}
- 快速明晰支持哪些类型
- 快速明晰功能划分思路
3.2 是否产生实体对象
export const enum SplitStyleEnum {
style11 = 'style11',
style12 = 'style12',
style21 = 'style21',
style22 = 'style22',
antdStyle1 = 'antdStyle1',
style3 = 'style3',
}
- 使用
const enum修饰的枚举,build后,不会生成实体,即编译后代码是对应的值 const enum一般作为包内部使用,不对外暴露,可以降低代码大小
- 使用
enum修饰的枚举,build后,会生成实体,类似Object,即编译后代码是类源码 enum一般需要对外暴露,外部也可以使用此枚举,方便统一
3.3 快速获取所有枚举的列表
Object.values(FormItemTypeEnum)
- 能拿到上述枚举的所有字符串组成的列表
4. map使用技巧
4.1 当需要枚举的是一个对象时采用
// 表单编辑器type对应的映射对象
export const FormItemMap: IFormItemMap = {
[FormItemTypeEnum.INPUT]: {
modelType: ModelItemTypeEnum.TEXT,
title: '单行文本输入框',
defaultData: defaultData.inputData,
},
[FormItemTypeEnum.INPUTNUMBER]: {
modelType: ModelItemTypeEnum.DECIMAL,
title: '数值输入框',
defaultData: defaultData.inputNumberData,
},
...
};
4.2 简化遍历逻辑
formItems.map((curFormItem) => {
// 若组件类型名称异常,使用默认的名称
if (!curFormItem.title) {
curFormItem.title = FormItemMap[curFormItem.type]?.title;
}
const curDefaultData = FormItemMap[curFormItem.type]?.defaultData;
if (curDefaultData) {
return mergeData(curFormItem, curDefaultData);
}
return curFormItem;
});