如何让TypeScript支持递归this类型?扩展对象函数this类型问题
让TypeScript识别递归this类型的解决方案
你的问题核心是扩展方法需要同时访问基础对象和其他扩展方法的属性/方法,但当前类型约束导致TypeScript无法正确推断this的递归类型。以下是两种可行的解决方式:
方法一:使用ThisType工具类型(推荐)
TypeScript提供的ThisType<T>工具类型可以专门用来指定对象字面量中函数的this指向,无需修改原有ThingBase接口的定义:
interface ThingBase { method(): string; data: string; } function makeThing<Ext extends Record<string, (...args: any[]) => any>>( extension: Ext & ThisType<ThingBase & Ext> ): ThingBase & Ext { return { ...extension, method() { return "hello" }, data: "yes" } } const thingWithExt = makeThing({ yello: function() { return this.data; // 正常识别 }, mmm: function() { return this.yello(); // 不再报错,正确识别this包含yello方法 } }); const d = thingWithExt.yello(); // 类型推断正确
原理说明
ThisType<ThingBase & Ext>会告诉TypeScript:extension对象内所有函数的this上下文是ThingBase和Ext的交叉类型。它不会改变对象的类型结构,只是给TypeScript提供this的类型提示,完美解决了递归访问扩展方法的问题,同时保留ThingBase的强类型约束。
方法二:给ThingBase添加索引签名(不推荐)
如果不想使用ThisType,可以给ThingBase添加一个字符串索引签名,让TypeScript允许访问任意字符串属性:
interface ThingBase { method(): string; data: string; [key: string]: any; // 添加可选索引签名 } function makeThing< Ext extends {[index:string]: (this: ThingBase & Ext, ...args:any[]) => any} >(extension: Ext): ThingBase & Ext { return { ...extension, method() { return "hello" }, data: "yes" } } const thingWithExt = makeThing({ yello: function() { return this.data; }, mmm: function() { return this.yello(); // 不再报错 } });
注意事项
这种方式会弱化ThingBase的类型检查,比如允许访问this.nonExistentProperty而不报错,因此仅作为备选方案。
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

