如何按类型遍历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
相关产品推荐
相关产品推荐

