前言
在开发过程中当需要根据不同的数据类型来处理逻辑时,我们通常会定义这样的数据字典:
上图中可以看到,ts给出了类型提示,但并没有注释信息。
那有没有方法能够给DATA_TYPE.SUM
的类型提示添加注释信息呢?
效果 + 代码实现
在经过很多尝试后,突然想到了一个很骚的方案,话不多说直接上效果:
鼠标放在DATA_TYPE
上,也能看到所有值的注释
我们的DATA_TYPE.SUM
的类型提示终于有了“注释”!
但细心的小伙伴肯定已经发现了,这其实就是一个联合类型的写法。
虽然DATA_TYPE.SUM
的类型是个联合类型,但它的值其实只有4
,使用联合类型只是我能想到的加注释最好的方式了。
为了实现上面的效果,实现了一个defineDict()
函数,代码如下:
type DictOptions = Record<string, { label: string; value: any }>;
export function defineDict<T extends DictOptions>(options: T) {
const dictMap = new Map<string, { key: string; value: any; label: string }>();
const dict: {
[key in keyof T]: T[key]["value"] | `/* ${T[key]["label"]} */`;
} = {} as any;
Object.entries(options).forEach(([key, item]) => {
dictMap.set(item.value, {
key,
value: item.value,
label: item.label,
});
dict[key as keyof T] = item.value;
});
return {
...dict,
getLabel(v: any) {
return dictMap.get(v)?.label;
},
createOptions() {
return Array.from(dictMap.values()).map((item) => ({
label: item.label,
value: item.value,
}));
},
};
}
其中就靠这段代码就实现了这个“注释”效果
const dict: {
[key in keyof T]: T[key]["value"] | `/* ${T[key]["label"]} */`;
} = {} as any;
实现其实并不复杂,就是联合类型的那根竖线有点膈应,哈哈。
其他作用
因为在定义的时候添加了label
字段,我们的数据字典就有了更多的使用场景
getLabel()
:通过value
获取对应label
,在做数据类型回显的时候就很有用
const numLabel = DATA_TYPE.getLable(4);
createOptions()
:根据字典数据创建一个Array<{label: string, value: any}>
类型的数组,在做数据字典下拉选择器的时候也很有用
const dataTypeOptions = DATA_TYPE.createOptions();
结语
这种实现方式虽然有点反常规,但至少确实是能看到注释,就当我抛砖引玉了。如果小伙伴们有更好的的方式,欢迎在评论区交流~