You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript元组首元素返回类型隐式推断验证问题

TypeScript类型推断验证实现问题

我需要实现如下TypeScript类型推断验证,核心需求是让validate函数的第二个参数数组中,每个元组的断言函数返回值类型必须和对应的验证器参数类型匹配——比如用validateNumber验证字符串类型的属性时,TypeScript能自动抛出错误。

现有代码:

interface Animal {
  name: string;
  color: string;
  age: number;
}
type Validator<T> = (data: T) => boolean;

const validateString: Validator<string> = (data) => !!data?.length;
const validateNumber: Validator<number> = (data) => data > 0;

// 需实现类型推断的类型(当前版本无法实现期望校验)
type ValidatorTuple<T> = [(data: T) => unknown, Validator<unknown>];

const validate = <T>(item: T, validator: ValidatorTuple<T>[]) => {
  for (const [predicate, validation] of validator) {
    const value = predicate(item);
    const result = validation(value);
    if (!result) return false;
  }
  return true;
};

// 期望效果:第三个元组中用validateNumber验证d.name(string类型)应触发TS错误
const dog: Animal = {
  age: 12,
  color: "white",
  name: "josh",
};

const isValid = validate(dog, [
  [(d) => d.age, validateNumber],
  [(d) => d.color, validateString],
  [(d) => d.name, validateNumber], // 此处应触发TS错误
]);

我尝试了多种TypeScript推断方式,但均无法实现上述期望的类型校验效果。


解决方案

要实现这个类型校验,需要让ValidatorTuple<T>关联断言函数的返回值类型和验证器的参数类型,具体可以通过泛型约束来实现:

interface Animal {
  name: string;
  color: string;
  age: number;
}
type Validator<T> = (data: T) => boolean;

const validateString: Validator<string> = (data) => !!data?.length;
const validateNumber: Validator<number> = (data) => data > 0;

// 重新定义ValidatorTuple,用泛型K绑定断言返回值与验证器参数类型
type ValidatorTuple<T> = <K>([(data: T) => K, Validator<K>]);

// 调整validate函数的参数类型,确保数组内每个元组的类型一致性
const validate = <T>(item: T, validator: Array<ValidatorTuple<T>[0]>) => {
  for (const [predicate, validation] of validator) {
    const value = predicate(item);
    const result = validation(value);
    if (!result) return false;
  }
  return true;
};

const dog: Animal = {
  age: 12,
  color: "white",
  name: "josh",
};

const isValid = validate(dog, [
  [(d) => d.age, validateNumber], // 正常:number类型匹配Validator<number>
  [(d) => d.color, validateString], // 正常:string类型匹配Validator<string>
  [(d) => d.name, validateNumber], // TS错误:类型'string'的参数不能赋给类型'number'的参数
]);

原理说明

  • 给ValidatorTuple<T>添加泛型K,K代表从T中提取的属性类型,让断言函数的返回值类型与验证器的参数类型强绑定。
  • 将validate函数的第二个参数定义为Array<ValidatorTuple<T>[0]>,允许数组包含任意属性对应的元组,但强制每个元组内部的类型必须一致。

内容的提问来源于stack exchange,提问作者Cosimo Chellini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 23:10:51