TypeScript Checker如何获取指定位置局部this的Symbol与类型
获取函数内局部
this类型的实现方案 checker.getSymbolsInScope 本身不会返回this相关条目,因为this是函数级别的隐式上下文绑定,不属于普通作用域内声明的标识符,需要通过函数签名的专属属性获取,方案兼容你提到的所有场景。
核心实现逻辑
- 首先定位目标位置对应的AST节点,沿父节点向上查找,跳过不绑定自身
this的箭头函数,找到最近的非箭头函数类节点(包含类方法、普通函数声明、对象字面量方法等所有FunctionLike类型节点)。 - 对找到的函数节点,通过TypeChecker获取其对应的签名实例,签名上的
thisParameter属性就是该函数this值对应的符号——不管是显式声明的this参数,还是类/对象方法隐式生成的this绑定,TS都会在签名上挂载这个符号。 - 最后通过
checker.getTypeOfSymbolAtLocation即可拿到this的准确类型。如果一路向上查找到源文件根节点都没有找到绑定this的函数,直接取全局this类型即可。
可直接复用的代码示例
function getThisTypeAtPosition( program: ts.Program, sourceFile: ts.SourceFile, offset: number ): ts.Type | undefined { const checker = program.getTypeChecker(); // 查找指定偏移位置对应的最内层AST节点 const getNodeAtOffset = (node: ts.Node): ts.Node | undefined => { if (node.pos <= offset && node.end >= offset) { return ts.forEachChild(node, getNodeAtOffset) ?? node; } return undefined; }; let current = getNodeAtOffset(sourceFile); while (current) { // 箭头函数无自身this绑定,向上继承外层this if (ts.isArrowFunction(current)) { current = current.parent; continue; } // 命中有自身this绑定的函数节点 if (ts.isFunctionLike(current)) { const signature = checker.getSignatureFromDeclaration(current); if (signature?.thisParameter) { return checker.getTypeOfSymbolAtLocation(signature.thisParameter, current); } } current = current.parent; } // 顶层作用域返回全局this类型 return checker.getGlobalThisType(); }
场景适配验证
- 类方法内@1位置:返回
MyClass实例类型,可通过checker.getPropertiesOfType拿到类的所有属性、方法成员。 - 显式声明
this: MyClass的函数内@2位置:返回手动声明的MyClass类型,和标注类型完全一致。 - 对象字面量方法内@3位置:返回对应对象的结构类型,即包含
bar方法的{ bar(): void }类型,符合JS原生this绑定规则。
拿到类型后直接调用checker.getCompletionEntryDetails或者遍历类型成员,就能实现你需要的如下补全效果:
内容的提问来源于stack exchange,提问作者Henning Dieterichs
相关产品推荐
相关产品推荐

