TypeScript泛型类型约束:如何确保泛型的所有属性均实现指定接口
TypeScript泛型类型约束:如何确保泛型的所有属性均实现指定接口
当然可以解决这个问题!你只需要给泛型TSort添加一个类型约束,确保它的所有属性值都实现了ISortableItem接口,TypeScript编译器就会认可value.ordinality的访问了。
问题原因
你之前的泛型TSort没有任何类型限制,TypeScript无法推断出它的属性值包含ordinality属性,所以会抛出类型错误。通过添加约束,我们可以明确告诉编译器:这个泛型对象的每一个属性值都必须符合ISortableItem的结构。
解决方案
我们可以使用TypeScript的Record工具类型来定义约束,或者直接用索引签名的方式。这里用Record会更简洁直观:
type Entries<T> = { [K in keyof T]: [K, T[K]]; }[keyof T][]; interface ISortableItem { ordinality: number; } class SortClass { name: ISortableItem; population: ISortableItem; // 添加构造函数初始化属性,避免实例化时报错 constructor() { this.name = { ordinality: 1 }; this.population = { ordinality: 2 }; } } // 给TSort添加约束:所有属性值必须是ISortableItem类型 function sortObject<TSort extends Record<string, ISortableItem>>(obj: TSort) { const objects = Object.entries(obj) as Entries<TSort>; for (const [key, value] of objects) { console.log(value.ordinality); // 现在不会再报错了 } } // 测试调用 const sortInstance = new SortClass(); sortObject(sortInstance); // 输出:1、2
补充说明
- 如果你的对象键可能包含
number或symbol类型,可以把约束改成Record<string | number | symbol, ISortableItem>,这样能覆盖所有合法的对象键类型。 - 也可以用索引签名的方式写约束:
TSort extends { [key: string]: ISortableItem },效果和Record<string, ISortableItem>是一致的。
这样修改后,不仅能解决编译器报错的问题,还能在调用sortObject时自动校验传入的对象是否符合要求——如果传入的对象有某个属性值没有实现ISortableItem,TypeScript会提前抛出错误,避免运行时问题。
备注:内容来源于stack exchange,提问作者killjoy
相关产品推荐
相关产品推荐

