TypeScript如何约束泛型的指定属性实现includes等特定方法
实现方案
核心思路
新增第二个泛型参数约束属性名的合法范围,同时定义类型约束对应属性必须实现符合要求的includes方法,不需要硬编码属性名,完全通过TypeScript类型系统完成静态校验。
完整实现代码
写法1(更简洁易读)
// 通用类型:匹配所有可接收string作为参数调用includes方法的类型 interface IncludesAble<Item = string> { includes(searchValue: Item, fromIndex?: number): boolean; } function customFilter<T extends Record<K, IncludesAble<string>>, K extends keyof T>( values: T[], filterString: string, propName: K ): T[] { return values.filter((value) => value[propName].includes(filterString)); }
写法2(条件类型实现,效果与写法1完全一致)
interface IncludesAble<Item = string> { includes(searchValue: Item, fromIndex?: number): boolean; } function customFilter<T, K extends keyof T>( values: T[], filterString: string, propName: T[K] extends IncludesAble<string> ? K : never ): T[] { return values.filter((value) => value[propName].includes(filterString)); }
约束效果验证
我们可以用实际类型测试校验规则是否生效:
interface User { name: string; tags: string[]; age: number; } const testUsers: User[] = []; // ✅ 合法:name为string类型,符合约束 customFilter(testUsers, 'test', 'name'); // ✅ 合法:tags为string数组,支持传入string调用includes customFilter(testUsers, 'admin', 'tags'); // ❌ 类型错误:age为number类型,没有符合要求的includes方法 customFilter(testUsers, '20', 'age');
扩展说明
如果后续需要支持其他类型的搜索值,只需要调整IncludesAble的泛型参数和filterString的类型即可,不需要修改整体约束逻辑。
内容的提问来源于stack exchange,提问作者b4ux1t3
相关产品推荐
相关产品推荐

