TypeScript泛型接口实现:能否传入自定义类型而非原生类型?
问题描述
在实现泛型接口时,能否将自定义类型传入泛型参数,还是只能传入TypeScript原生类型(如string、number等)?
代码示例:
type coordinates = { x: string; y: string; }; interface polygon { convert<T>(cord: T): string; } class triangle implements polygon { public cord: coordinates; constructor(cord: coordinates) { this.cord = cord; } convert(cord: coordinates): string { return "the coordinates is x:" + cord.x + " y:" + cord.y; } }
使用TypeScript 4.9.5版本时,编辑器在convert方法实现处报错:
The property 'convert' in type 'triangle' is not assignable to the same property in base type
polygon.
Type(cord: coordinates) => stringis not assignable to type<T>(cord: T) => string.
Types of parameters 'cord' and 'cord' are incompatible.
Type 'T' is not assignable to type 'coordinates'.
解答
当然可以将自定义类型作为泛型参数传入,并非只能使用TypeScript原生类型。你当前的错误不是因为自定义类型不能用,而是接口和实现类的泛型定义不匹配。
问题根源
你定义的polygon接口中,convert是一个泛型方法——这意味着任何实现该接口的类,必须让convert方法能接受任意类型的T参数。但你的triangle类里的convert方法只接受coordinates类型,这就违反了接口的要求,所以TypeScript报错。
修正方案
根据你的需求,有两种常见的修正方式:
方案1:将泛型定义在接口层面(推荐)
把泛型参数移到接口本身,实现类时指定具体的自定义类型,这样整个接口的方法就绑定到该类型上:
type coordinates = { x: string; y: string; }; // 泛型参数T定义在接口层面 interface polygon<T> { convert(cord: T): string; } // 实现时指定自定义类型coordinates作为泛型参数 class triangle implements polygon<coordinates> { public cord: coordinates; constructor(cord: coordinates) { this.cord = cord; } convert(cord: coordinates): string { return "the coordinates is x:" + cord.x + " y:" + cord.y; } }
方案2:给泛型方法添加类型约束
如果确实需要convert保持为泛型方法,但只想处理自定义类型,可以给T添加约束,限制它必须是coordinates或其子类型:
type coordinates = { x: string; y: string; }; interface polygon { // 约束T必须是coordinates的子类型 convert<T extends coordinates>(cord: T): string; } class triangle implements polygon { public cord: coordinates; constructor(cord: coordinates) { this.cord = cord; } // 实现时也需要保持泛型约束 convert<T extends coordinates>(cord: T): string { return "the coordinates is x:" + cord.x + " y:" + cord.y; } }
内容的提问来源于stack exchange,提问作者user21405000

