TypeScript中如何实现接收自身类型的接口函数多态?
在TypeScript中定义接收自身类型参数的接口层级函数
问题场景
想要定义一套接口层级,让基接口声明的函数,在每个扩展接口中仅接收自身接口类型而非基类型。最初的尝试代码如下:
interface IBase { a: string, f: (x: IBase) => any // 问题根源 } interface IExtension extends IBase { b: string, } const f1 = (x: IExtension) => { /* 使用x.b时类型检查通过 */ }; const ext1: IExtension = { a: "a1", b: "b1", f: f1 // 类型检查失败 };
对应的错误提示:
Type '(x: IExtension) => {}[]' is not assignable to type '(x: IBase) => any'
方法语法的妥协方案
将函数属性改为方法语法后,类型检查可以通过:
interface IBase { a: string, f(x: IBase): any }
这是因为TypeScript的strictFunctionTypes规则对方法采用双向协变(对普通函数类型则采用逆变),允许这种赋值。但该方案存在严重的类型不安全问题:如果通过IBase类型的引用调用f,传入仅符合IBase的对象,运行时会因缺少扩展接口的属性(如b)报错,无法保证f被调用时传入的是自身接口类型的实例。
非泛型的健全方案是否存在?
目前TypeScript没有原生非泛型语法可以健全地表达“函数参数必须是当前接口自身类型”的约束。这种需求本质是递归类型依赖,需要将接口与自身类型绑定,而泛型是实现这种绑定的唯一健全方式:
interface IBase<T extends IBase<T>> { a: string; f: (x: T) => any; } interface IExtension extends IBase<IExtension> { b: string; } const f1 = (x: IExtension) => { /* 安全使用x.b */ }; const ext1: IExtension = { a: "a1", b: "b1", f: f1 // 类型检查通过且安全 };
如果坚持不使用泛型,只能接受方法语法带来的类型不安全性,这是当前的权衡选择。
内容的提问来源于stack exchange,提问作者usernolan
相关产品推荐
相关产品推荐

