以下是一个使用 TypeScript 高级类型实现的通用表单校验函数方案,包含泛型约束和类型安全设计:

核心实现

// 定义校验规则类型
type Validator<T> = (value: T) => string | null;

// 定义字段校验规则
type FieldRules<T> = {
  [K in keyof T]?: Validator<T[K]> | Validator<T[K]>[];
};

// 定义校验结果类型
type ValidationResult<T> = {
  [K in keyof T]?: string[];
} & {
  isValid: boolean;
};

/**
 * 通用表单校验函数
 * @param formData 表单数据对象
 * @param rules 校验规则配置
 * @returns 校验结果对象
 */
function validateForm<T extends Record<string, any>>(
  formData: T,
  rules: FieldRules<T>
): ValidationResult<T> {
  const result: ValidationResult<T> = { isValid: true };
  
  Object.keys(rules).forEach((key) => {
    const validators = rules[key as keyof T];
    if (!validators) return;
    
    const value = formData[key as keyof T];
    const errors: string[] = [];
    
    // 处理单个或多个校验器
    const validatorList = Array.isArray(validators) 
      ? validators 
      : [validators];
    
    validatorList.forEach((validator) => {
      const error = validator(value);
      if (error) errors.push(error);
    });
    
    // 记录错误信息
    if (errors.length > 0) {
      result[key as keyof T] = errors;
      result.isValid = false;
    }
  });
  
  return result;
}

类型说明

  1. 泛型约束

    T extends Record<string, any>
    

    确保表单数据类型为键值对对象

  2. 动态字段校验

    type FieldRules<T> = {
      [K in keyof T]?: Validator<T[K]> | Validator<T[K]>[];
    };
    

    自动映射表单字段类型,为每个字段提供类型匹配的校验函数

  3. 校验结果类型安全

    type ValidationResult<T> = {
      [K in keyof T]?: string[];
    } & {
      isValid: boolean;
    };
    

    返回结果包含字段错误信息数组和整体校验状态

使用示例

// 1. 定义表单类型
interface UserForm {
  username: string;
  age: number;
  email: string;
}

// 2. 创建校验规则
const userRules: FieldRules<UserForm> = {
  username: [
    (val) => val.trim().length >= 3 || "用户名至少3个字符",
    (val) => /^[a-zA-Z0-9_]+$/.test(val) || "只能包含字母数字和下划线"
  ],
  age: (val) => val >= 18 || "必须年满18岁",
  email: (val) => 
    /^\S+@\S+\.\S+$/.test(val) || "邮箱格式不正确"
};

// 3. 使用校验函数
const formData: UserForm = {
  username: "a#b",
  age: 16,
  email: "invalid-email"
};

const result = validateForm(formData, userRules);

/* 输出结果:
{
  username: ["只能包含字母数字和下划线"],
  age: ["必须年满18岁"],
  email: ["邮箱格式不正确"],
  isValid: false
}
*/

高级特性说明

  1. 嵌套对象校验: 通过递归类型定义支持嵌套表单结构:

    type DeepFieldRules<T> = {
      [K in keyof T]?: T[K] extends object 
        ? DeepFieldRules<T[K]> 
        : Validator<T[K]> | Validator<T[K]>[];
    };
    

  2. 异步校验支持: 修改校验器返回 Promise 类型:

    type AsyncValidator<T> = (value: T) => Promise<string | null>;
    

  3. 条件校验: 使用条件类型实现动态规则:

    type ConditionalRule<T> = {
      when: (data: T) => boolean;
      rule: Validator<T[keyof T]>;
    };
    

数学表达式的应用

在复杂校验场景中,可使用数学表达式增强校验逻辑:

// 价格校验:必须满足 $price > cost \times 1.2$
const priceRule: Validator<number> = (price) => 
  price > cost * 1.2 
    ? null 
    : "价格必须高于成本20%";

// 坐标校验:需满足 $\sqrt{x^2 + y^2} \leq maxDistance$
const coordinateRule: Validator<[number, number]> = ([x, y]) => 
  Math.sqrt(x**2 + y**2) <= maxDistance
    ? null
    : "超出允许距离范围";

此实现通过 TypeScript 的高级类型系统,提供了:

  1. 完整的类型安全保证
  2. 灵活的校验规则配置
  3. 清晰的错误信息结构
  4. 可扩展的校验能力
  5. 自动化的类型推断支持
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐