添加ts从vo自动转换到dto

This commit is contained in:
LittleBoy 2025-07-19 11:43:04 +08:00
parent d69bdfea12
commit e88210a9bc

View File

@ -0,0 +1,229 @@
import Schema, { Rules } from 'async-validator';
// 定义字段元数据接口
interface FieldMetadata {
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
voField?: string;
rules?: Rules;
nestedSchema?: SchemaBuilder<any>;
}
// 链式API构建器类
class SchemaBuilder<T> {
private fields: Record<string, FieldMetadata> = {};
private currentField: string | null = null;
private currentMetadata: FieldMetadata | null = null;
constructor(private name: string) {}
// 添加字段
field<K extends string>(name: K): SchemaBuilder<T & { [P in K]: any }> {
this.currentField = name;
this.currentMetadata = { type: 'string' };
return this as unknown as SchemaBuilder<T & { [P in K]: any }>;
}
// 设置字段类型
type(type: FieldMetadata['type']): this {
if (this.currentMetadata) {
this.currentMetadata.type = type;
}
return this;
}
// 设置VO字段映射
voField(name: string): this {
if (this.currentMetadata) {
this.currentMetadata.voField = name;
}
return this;
}
// 添加验证规则
validate(rules: Rules): this {
if (this.currentMetadata) {
this.currentMetadata.rules = rules;
}
return this;
}
// 设置嵌套Schema
nested(schema: SchemaBuilder<any>): this {
if (this.currentMetadata) {
this.currentMetadata.nestedSchema = schema;
this.currentMetadata.type = 'object';
}
return this;
}
// 完成字段定义
end(): this {
if (this.currentField && this.currentMetadata) {
this.fields[this.currentField] = this.currentMetadata;
this.currentField = null;
this.currentMetadata = null;
}
return this;
}
// 生成TypeScript类型
getType(): T {
return {} as T;
}
// 生成验证规则
getValidationRules(): Rules {
const rules: Rules = {};
for (const [field, metadata] of Object.entries(this.fields)) {
if (metadata.rules) {
rules[field] = metadata.rules;
}
// 处理嵌套对象
if (metadata.nestedSchema) {
rules[field] = { ...rules[field], fields: metadata.nestedSchema.getValidationRules() };
}
}
return rules;
}
// 获取字段元数据
getFieldsMetadata(): Record<string, FieldMetadata> {
return { ...this.fields };
}
}
// 创建Schema构建器的工厂函数
function createSchema<T = {}>(name: string): SchemaBuilder<T> {
return new SchemaBuilder<T>(name);
}
// 从Schema提取TypeScript类型的工具类型
type ExtractTypeFromSchema<T> = T extends SchemaBuilder<infer U> ? U : never;
// 生成验证规则
function createRules<T>(schema: SchemaBuilder<T>): Rules {
return schema.getValidationRules();
}
// VO到DTO的转换函数
function transformVoToDto<T>(data: any, schema: SchemaBuilder<T>): T {
const fields = schema.getFieldsMetadata();
const result: any = {};
for (const [dtoField, metadata] of Object.entries(fields)) {
const voField = metadata.voField || dtoField;
const value = data[voField];
// 处理嵌套对象
if (metadata.nestedSchema && typeof value === 'object' && value !== null) {
result[dtoField] = transformVoToDto(value, metadata.nestedSchema);
} else {
// 根据类型转换值
switch (metadata.type) {
case 'number':
result[dtoField] = Number(value);
break;
case 'boolean':
result[dtoField] = Boolean(value);
break;
default:
result[dtoField] = value;
}
}
}
return result as T;
}
// 带转换功能的API请求函数
async function get<T>(url: string, schema: SchemaBuilder<T>): Promise<T> {
// 模拟API请求
const response = await fetch(url);
const voData = await response.json();
// 转换VO到DTO
const dtoData = transformVoToDto(voData, schema);
// 验证数据
const validator = new Schema(schema.getValidationRules());
try {
await validator.validate(dtoData);
} catch (errors) {
// 确保验证错误被正确抛出
throw new Error(`Validation failed: ${JSON.stringify(errors)}`);
}
return dtoData;
}
// Fix the export statement to ensure proper ESM exports
export { createSchema, createRules, get, transformVoToDto, ExtractTypeFromSchema };
// 创建地址Schema
const AddressSchema = createSchema('Address')
.field('street')
.type('string')
.voField('streetName')
.validate({ required: true, min: 2, max: 100 })
.end()
.field('city')
.type('string')
.validate({ required: true })
.end()
.field('zipCode')
.type('string')
.voField('postalCode')
.validate({ required: true, pattern: /^\d{5}$/ })
.end();
// 创建用户Schema
const UserSchema = createSchema('User')
.field('id')
.type('number')
.voField('userId')
.validate({ required: true, type: 'number' })
.end()
.field('name')
.type('string')
.validate({ required: true, min: 2, max: 50 })
.end()
.field('email')
.type('string')
.validate({
required: true,
type: 'string',
pattern: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/,
})
.end()
.field('age')
.type('number')
.validate({ type: 'number', min: 0, max: 150 })
.end()
.field('address')
.type('object')
.nested(AddressSchema)
.validate({ type: 'object' })
.end();
// 提取用户类型
type User = ExtractTypeFromSchema<typeof UserSchema>;
// 获取验证规则
const userRules = createRules(UserSchema);
// 使用示例
async function fetchUser() {
try {
const user = await get<User>('/api/user/1', UserSchema);
console.log('用户数据:', user);
return user;
} catch (error) {
console.error('获取用户失败:', error);
}
}
// 执行示例
fetchUser();