You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 09:50:14