TypeScript中如何优雅实现与实体类字段一致的权重类?
解决方案
方案1:用映射类型同步类结构
先定义核心的字段结构,再通过TypeScript的映射类型自动生成权重类型,最后让类实现对应的类型——这样只需要维护一份结构,就能保证两个类的字段一致性:
// 核心字段结构,所有增删改操作只需要修改这里 type EntityFields = { id: string; uuid: string; firstname: string; lastname: string; }; // 自动生成权重类型,字段名和EntityFields完全一致,类型替换为number type EntityWeightsFields = { [Key in keyof EntityFields]: number; }; // 实现实体类 class Entity implements EntityFields { public id!: string; public uuid!: string; public firstname!: string; public lastname!: string; } // 实现权重类,结构被TypeScript强制约束和Entity一致 class EntityWeights implements EntityWeightsFields { public id!: number; public uuid!: number; public firstname!: number; public lastname!: number; }
方案2:用泛型类复用结构
直接定义一个泛型类,把字段的类型作为参数传入,一次定义就能生成实体和权重两种类,完全不需要维护两份代码:
class BaseEntity<T> { public id!: T; public uuid!: T; public firstname!: T; public lastname!: T; } // 用类型别名快速生成需要的类类型 type Entity = BaseEntity<string>; type EntityWeights = BaseEntity<number>; // 实例化时直接指定类型参数 const userEntity = new BaseEntity<string>(); const userWeights = new BaseEntity<number>();
解决拆分值/权重的问题
如果需要处理值和权重的分离传递,比如给putInDB传纯值对象,可以用以下两种方式:
方式1:针对[值, 权重]嵌套结构的拆分工具
如果已经用了字段嵌套的写法,可以写简单的工具函数提取对应内容:
// 定义嵌套结构的类型 type EntityWithNestedWeights = { [Key in keyof EntityFields]: [string, number]; }; // 提取纯值的工具函数 function getPureValues(entity: EntityWithNestedWeights): EntityFields { const pureValues: Partial<EntityFields> = {}; for (const key in entity) { pureValues[key] = entity[key][0]; } return pureValues as EntityFields; } // 使用示例 const nestedEntity: EntityWithNestedWeights = { id: ['u1001', 0.6], uuid: ['abc-123', 0.9], firstname: ['Alice', 1.0], lastname: ['Smith', 0.7] }; // 传给DB的纯值对象 putInDB(getPureValues(nestedEntity));
方式2:用组合类分离值和权重(更推荐)
把值和权重作为独立属性放在同一个类里,结构更清晰,也避免嵌套的麻烦:
class EntityWithWeights { public values: Entity = new Entity(); public weights: EntityWeights = new EntityWeights(); } // 使用时直接操作对应属性 const combinedEntity = new EntityWithWeights(); combinedEntity.values.id = 'u1001'; combinedEntity.weights.id = 0.6; // 传给DB时直接传values属性 putInDB(combinedEntity.values);
内容的提问来源于stack exchange,提问作者BenGee23
相关产品推荐
相关产品推荐

