MST

星途 面试题库

面试题:TypeScript泛型约束在复杂场景下的深度应用

假设有一个复杂的表单数据结构,每个表单字段都有一个唯一的标识符 `id`,并且每个字段都有不同的验证规则。设计一个泛型函数 `validateForm`,它接受一个表单数据对象和一个验证器对象。通过泛型约束,确保验证器对象中的每个验证函数都与表单数据对象中对应 `id` 的字段类型匹配。同时,验证器对象中的验证函数返回一个布尔值表示验证是否通过。实现该泛型函数并详细说明泛型约束是如何设计和应用的。
37.1万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
// 定义验证器函数类型
type ValidatorFunction<T> = (value: T) => boolean;

// 泛型函数,T 表示表单数据类型,V 表示验证器类型
function validateForm<T extends { [key: string]: any }, V extends { [K in keyof T]?: ValidatorFunction<T[K]> }>(
  formData: T,
  validators: V
): boolean {
  for (const key in formData) {
    if (Object.prototype.hasOwnProperty.call(formData, key) && validators[key]) {
      const value = formData[key];
      const validator = validators[key] as ValidatorFunction<typeof value>;
      if (!validator(value)) {
        return false;
      }
    }
  }
  return true;
}

// 示例用法
const formData = {
  name: 'John',
  age: 30,
  email: 'john@example.com'
};

const validators = {
  name: (value: string) => value.length > 0,
  age: (value: number) => value > 0 && value < 120,
  email: (value: string) => value.includes('@')
};

const isValid = validateForm(formData, validators);
console.log(isValid); 

泛型约束设计与应用说明

  1. T 泛型约束T extends { [key: string]: any } 表示 T 是一个对象类型,其属性的键是字符串类型,值可以是任意类型。这确保了传入的 formData 是一个符合表单数据结构要求的对象。
  2. V 泛型约束V extends { [K in keyof T]?: ValidatorFunction<T[K]> } 这个约束比较复杂。首先,[K in keyof T] 表示 V 的属性键与 T 的属性键一一对应。?: 表示这些属性是可选的,因为可能某些表单字段不需要验证。ValidatorFunction<T[K]> 表示 V 中对应属性的值是一个验证函数,且该验证函数接收的参数类型与 T 中对应属性的值类型相同。这样就确保了验证器对象中的每个验证函数都与表单数据对象中对应 id(属性键)的字段类型匹配。在函数内部,通过遍历 formData 对象的属性,对每个存在验证器的字段进行验证,如果有任何一个验证不通过,则返回 false,全部通过则返回 true