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

如何实现TypeScript泛型数组类型谓词以校验对象属性类型?

解决方案:泛型类型谓词实现对象与类属性的数组类型校验

一、修复对象实例的数组属性校验函数

你之前的写法问题在于,TypeScript对T[P] is Array<any>这种属性级别的类型谓词,在处理带索引签名的对象时无法正确完成类型收窄。调整为断言整个对象的指定属性为数组类型即可解决:

function isArrayProperty<T, P extends keyof T>(
  obj: T,
  prop: P,
): obj is T & { [K in P]: Array<any> } {
  return Array.isArray(obj[prop]);
}

用你的测试代码验证:

const a: { [key in string]: string | string[]} = {
  arrayProp: ["this", "is", "an", "array"],
  otherProp: "this is a string"
};
Object.keys(a).forEach((prop: keyof typeof a) => {
  if (isArrayProperty(a, prop)) {
    // 此处a[prop]已被正确识别为数组类型
    a[prop].push("another value");
  }
});

二、实现类构造函数的数组属性校验

由于TypeScript类型信息在编译后会被擦除,必须依赖你提到的运行时Schema来判断类属性类型。假设你的Schema是一个映射类构造函数到属性类型的结构,实现如下:

1. 定义基础类型与运行时Schema示例

type ClassConstr<T> = new (...props: any[]) => T;

// 示例运行时Schema:根据你的实际结构调整
const classSchema = new Map<object, Record<string, "array" | "string" | "date">>();

2. 实现重载的校验函数

通过函数重载同时支持对象实例和类构造函数的校验:

// 重载1:校验对象实例的属性
function isArrayProperty<T, P extends keyof T>(
  obj: T,
  prop: P,
): obj is T & { [K in P]: Array<any> };

// 重载2:校验类构造函数对应的实例属性
function isArrayProperty<T, P extends keyof T>(
  obj: ClassConstr<T>,
  prop: P,
): T[P] is Array<any>;

// 统一实现逻辑
function isArrayProperty<T, P extends keyof T>(
  obj: T | ClassConstr<T>,
  prop: P,
): boolean {
  if (typeof obj === "function") {
    // 从运行时Schema获取属性类型判断
    const schema = classSchema.get(obj);
    return schema?.[prop as string] === "array";
  } else {
    return Array.isArray(obj[prop]);
  }
}

3. 使用示例

class A {
  someProp: any;
}

// 给类A注册运行时Schema
classSchema.set(A, {
  someProp: "array"
});

const a = new A();
a.someProp = ["some", "array"];

if (isArrayProperty(A, "someProp")) {
  // 此处a.someProp被正确识别为数组类型
  a.someProp.push("new value");
}

关键说明

  • 对象实例版本通过断言整个对象的属性类型,让TypeScript能正确完成索引签名类型的收窄。
  • 类构造函数版本完全依赖运行时Schema,因为TypeScript不会保留类属性的类型信息到运行时,无法通过构造函数或原型直接判断属性类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 07:55:19