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

如何按类型遍历TypeScript接口属性,实现可扩展搜索函数

基于类型的通用搜索函数重构

原代码与需求

定义的接口

interface StatusTO {
  name: string,
  identifier: string
}
export interface RowObject {
  partNumber: string,
  version: string,
  versionCount: number,
  status: StatusTO,
}

原有搜索函数

public isSearchedFor<T extends RowObject>(row: T, key: keyof T, searchTerm: string): boolean {
  let element = row[key];
  let stringValue: string | undefined = undefined;
  switch (key) {
    case 'partNumber':
    case 'version':
      stringValue = (element as string);
      break;
    case 'versionCount':
      stringValue = (element as number).toString();
      break;
    case 'status':
      stringValue = (element as StatusTO).name;
  }
  return stringValue?.includes(searchTerm) ?? false;
}

调用示例

const row = {
  partNumber: 'You have to FindMe',
  version: '123',
  versionCount: 2,
  status: {
    name: '200',
    identifier: 'OK'
  }
}
isSearchedFor(row, 'partNumber', 'FindMe'); // 返回true

需求

原有函数通过switch判断属性名处理不同类型属性,希望改为按属性类型(string、number、StatusTO)统一处理,新增同类型属性时无需修改函数以提升扩展性。需要解决复杂对象类型(如StatusTO)的类型判断问题,同时保证类型安全。


解决方案

1. 实现StatusTO的类型守卫

先编写类型守卫函数,让TypeScript能准确识别StatusTO类型的值:

function isStatusTO(value: unknown): value is StatusTO {
  return typeof value === 'object' && value !== null && 'name' in value && 'identifier' in value;
}

2. 重构搜索函数

去掉对属性名的硬编码判断,改为根据值的类型分支处理,新增同类型属性时无需修改函数:

public isSearchedFor<T extends RowObject>(row: T, key: keyof T, searchTerm: string): boolean {
  const element = row[key];
  let stringValue: string | undefined;

  if (typeof element === 'string') {
    stringValue = element;
  } else if (typeof element === 'number') {
    stringValue = element.toString();
  } else if (isStatusTO(element)) {
    stringValue = element.name;
  }

  return stringValue?.includes(searchTerm) ?? false;
}

3. 验证扩展性

假设给RowObject新增同类型属性:

export interface RowObject {
  partNumber: string,
  version: string,
  versionCount: number,
  status: StatusTO,
  statusDesc: string, // 新增string类型属性
  subStatus: StatusTO // 新增StatusTO类型属性
}

直接调用新增属性,函数无需修改即可正常工作:

const newRow = {
  ...row,
  statusDesc: 'Active',
  subStatus: { name: 'Running', identifier: 'RUN' }
};

isSearchedFor(newRow, 'statusDesc', 'Act'); // 返回true
isSearchedFor(newRow, 'subStatus', 'Run'); // 返回true

类型安全说明

  • 类型守卫isStatusTO确保在对应分支中,TypeScript能正确推断element为StatusTO类型,避免了原代码中类型断言的潜在风险。
  • 若传入的属性类型不在处理分支中,stringValue会是undefined,函数返回false,符合预期逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:32:26