DEBUG.WIKI
野草云;香港 200Mbps 峰值;不限月流量 · BGP VPS;查看套餐 →
腾讯云;让你的想法跑起来;轻量服务器 · 建站 / Docker / API;查看产品 →
阿里云;从建站到云上业务;云服务器 · 数据库 · 对象存储;查看产品 →

ESLint 给类型断言里的方法误报 Unexpected this

ESLint 10.13.0 的 no-invalid-this 可能被 TypeScript 的 as、satisfies 等包装阻断,认不出对象方法赋值。保留 this 调用语义,用上下文类型或显式 this 参数表达约束。

同一个函数直接赋给 obj.method 时没有 lint 提示,加上 as Fn、satisfies Fn 等 TypeScript 包装后,却在函数内部报 Unexpected 'this'.。如果仍然按 obj.method() 调用,应检查 no-invalid-this 对外层语法的判断。

ESLint 10.13.0 有这条具体误报路径。类型断言本身不会改变运行时 this,但规则向上查找函数使用位置时,可能在 TypeScript 包装节点处提前停止,没看到真正的对象成员赋值。

先确认 this 实际由谁提供

直接写 obj.method = function () { ... } 时,规则能识别这是成员赋值。函数外再包一层 as、类型断言、satisfies 或非空断言,运行代码中的赋值目的地没有改变,AST 形状却不同。

先检查实际 parser、最终规则配置及报错是否来自 ESLint 核心的 no-invalid-this。也要检查调用方有没有把方法拆出来单独调用,或者传给不保留接收者的回调接口;那时 this 真的可能丢失,不能用这条误报解释。

不要为了消除提示直接改成箭头函数。箭头函数捕获外层 this,不会像普通成员方法一样从调用处取得接收者,这可能把一个静态检查问题变成真实运行错误。

用类型上下文或显式 this 参数

如果断言原本只是补充一个已有方法签名,可以让对象类型提供上下文,不必再把整个函数包进断言。需要明确接收者时,也可以在普通函数声明 this 参数:

type Model = {
  value: number;
  update: () => void;
};

const model: Model = { value: 0, update() {} };

model.update = function (this: Model) {
  this.value = 1;
};

TypeScript 的 this 参数描述调用约束,不会生成一个额外运行时参数。ESLint 的相关判断也识别这种显式参数。接入业务时应保留真实方法的参数、返回值与接收者类型,不能把所有 this 都标为 any 来关闭类型保护。

如果断言还有其他必要含义,先评估是否能保留准确上下文。无法局部改写时,可以对已经人工核对调用语义的那一处使用说明清楚的规则豁免,继续检查其他位置;不宜全局关闭规则或添加无意义的 .bind() 让提示消失。

同时检查 lint 和真实调用方式

用项目原有的 TypeScript 检查与 ESLint 入口验证,确认被识别为成员方法的正确代码不再误报,真正没有接收者的普通函数仍会受到检查。编辑器与 CI 也应采用同一套实际依赖和 parser 配置。

最后沿原调用位置确认 this 指向预期对象,参数与返回行为保持一致。静态提示消失不能替代这项语义核对;后续更新规则时仍应保留包装形式的回归样本,再决定是否撤掉临时局部豁免。