type Constructor = new (...args: any[]) => T type DefaultType = number | string | boolean | (() => Record) | (() => Array) | (() => Map) | (() => Set)|(() => number); type NotNullableDefaultType = Exclude Constructor)>; interface PropType { // 属性值 defaultValue: any // 序列号化名 serializeName: string // 属性的构造器 constructor: Constructor } type PropTypes = Map /** * 不要赋值空字段,这里需要通过值判断类型,不支持,map,set,array和该注解的嵌套 * @param type 需要保存字段的类型 * @param defaultValue 需要保存字段的默认值 * @returns */ function saveProp(defaultValue: NotNullableDefaultType, serializeName?: string) { let res: PropertyDecorator = function (target: Object, prop: string) { let myConstructor = target.constructor as Constructor let valueMap = DataAnnotation.instance.propData.get(myConstructor) if (!valueMap) { valueMap = new Map DataAnnotation.instance.propData.set(myConstructor, valueMap) } if (defaultValue == undefined || defaultValue == null) { // 这里出现异常 throw new Error("未赋默认值") } serializeName = serializeName ?? prop // 获取默认属性,不然每次序列化都需要实例化 let defaultConstructor = null valueMap.set(prop, { defaultValue: defaultValue, serializeName: serializeName, constructor: defaultConstructor }) } return res } /** * * @param component 存储的根模块,如果不填,就默认为不是模块,和saveCompoent效果一样 * @param customize 用户是否自定义序列户方法,一旦启动,则用户需要自己实现unserialize和serialize方法 * @returns */ function saveRoot(componentName?: string, customize?: boolean) { return function (target: Constructor) { if (!componentName || componentName == "") { DataAnnotation.instance.saveCompoentSet.add(target) return } // 首字母小写注入 if (DataAnnotation.instance.root.get(componentName)) { // 这里出现异常 throw new Error("模块重复注入") } DataAnnotation.instance.root.set(componentName, target) DataAnnotation.instance.reregistMap.set(target, componentName) } } /** * 开启这个注解的类,会拥有序列化方法 * @returns */ function saveCompoent() { return function (target: Constructor) { // 首字母小写注入 DataAnnotation.instance.saveCompoentSet.add(target) } } /** * 存放注解相关内容 */ class DataAnnotation { /** 私有构造函数 */ private constructor() { } private static _instance: DataAnnotation /** 单例模式 */ public static get instance(): DataAnnotation { if (!this._instance) { this._instance = new this } return this._instance }; reregistMap: Map = new Map root: Map = new Map propData: Map = new Map saveCompoentSet: Set = new Set } /** * 全局的数据保存接口 */ export abstract class GlobalSaveData { constructor() { if (!GlobalSaveData.init) { this.initProp() } } private static init = false private initProp() { GlobalSaveData.init = true this.getClassMap().forEach(v => { let map = this.getPropMap().get(v) if (map) { map.forEach((v) => { let defaultValue = null if (typeof v.defaultValue == 'function') { defaultValue = v.defaultValue() } else { defaultValue = v.defaultValue } v.constructor = defaultValue?.constructor }) } }) } /** * saveRoot注册的类 */ getClassMap(): Map { return DataAnnotation.instance.root; } /** * saveData注册的变量 * @returns Constructor 函数构造器 */ getPropMap(): Map { return DataAnnotation.instance.propData; } getCompoentSet(): Set { return DataAnnotation.instance.saveCompoentSet; } /** * * @param key 需要反序列化的构造器 * @param saveData 需要反序列化的类 */ abstract unserialize(key: Constructor, saveData: any): T abstract serialize(data: T, key?: Constructor): Object; /** * 判断还类是不是注解类 */ isCompoent(compoent: Constructor): boolean { return this.getCompoentSet().has(compoent) || DataAnnotation.instance.reregistMap.has(compoent) } /** * 通过注册的类名获取描述信息 * @param compoent 模块类 */ getNameByConstructor(compoent: Constructor): string { return DataAnnotation.instance.reregistMap.get(compoent) } } // 继承接口的写法,应对比较复杂的类 abstract class SaveInterface { // 标记是不是一个类的方法 private static spuerTop = SaveInterface abstract serialize(): any; abstract unserialize(data: any): SaveInterface; } export { saveProp, saveRoot, // saveCompoent, SaveInterface } export type { PropTypes };