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

如何在自定义VSCode扩展中获取JavaScript表达式的类型信息?

获取VSCode模板字符串中表达式的类型(用于HTML属性类型校验扩展)

核心需求

我正在开发一个VSCode自定义扩展,用来对比HTML自定义属性与JavaScript表达式的类型。目前已通过JSDoc/TypeScript定义+NPM包实现HTML属性类型的获取,但卡在了获取模板字符串中嵌入表达式(如示例里的${page.SomeProperty})的类型上,同时需要支持以下复杂表达式场景:

  • 箭头函数:(args) => result
  • 函数调用:identifier.function()
  • 原始类型(string、number、boolean)
  • 复杂类型数组
  • 匿名对象
  • 匿名对象数组

示例代码:

/** @param {MyPage} page */
export function renderSomePage(page)
{
 return html`
 <my-component .my-attribute="${page.SomeProperty}"></my-component>
 `
}

可行实现方案

方案1:利用VSCode内置语言服务(推荐)

VSCode的TypeScript/JavaScript语言服务本身已掌握表达式的类型信息,无需自行解析语法树,可通过VSCode API直接调用:

  1. 获取当前文档的语言服务实例
    通过vscode.window.activeTextEditor拿到当前编辑器,再调用vscode.languages.getLanguageService获取对应TS/JS语言服务。

  2. 定位表达式位置
    通过正则匹配或AST解析工具(如@babel/parser),找到模板字符串中${}包裹的表达式在文档中的精确起止偏移量。

  3. 请求类型信息
    调用语言服务的getQuickInfoAtPosition方法,传入文档URI和表达式起始位置,返回的QuickInfo对象包含类型的显示文本、类型分类等信息,可直接提取使用。

示例代码片段:

import * as vscode from 'vscode';
import * as ts from 'typescript';

async function getExpressionType(editor: vscode.TextEditor, exprStartPos: number) {
  const doc = editor.document;
  const languageService = vscode.languages.getLanguageService({
    getTextDocument: (uri) => uri.toString() === doc.uri.toString() ? doc : undefined,
    getScriptFileNames: () => [doc.uri.fsPath],
    getScriptVersion: () => '1',
    getScriptSnapshot: (fileName) => fileName === doc.uri.fsPath ? ts.ScriptSnapshot.fromString(doc.getText()) : undefined,
    getCurrentDirectory: () => vscode.workspace.rootPath || '',
    getCompilationSettings: () => ({ allowJs: true, checkJs: true }),
    getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options)
  }) as ts.LanguageService;

  const quickInfo = languageService.getQuickInfoAtPosition(doc.uri.fsPath, exprStartPos);
  if (quickInfo) {
    return quickInfo.displayParts?.map(part => part.text).join('');
  }
  return null;
}

方案2:直接使用TypeScript Compiler API

若需要更底层的类型结构(如泛型参数、接口字段),可直接调用TypeScript编译API:

  1. 创建TS编译实例
    用ts.createProgram加载当前工作区代码,生成Program实例,需读取项目的tsconfig.json配置以保证类型推导准确。

  2. 定位表达式AST节点
    解析目标文件的SourceFile,遍历AST找到模板字符串中的表达式节点。

  3. 获取节点类型
    调用typeChecker.getTypeAtLocation传入表达式节点,拿到完整类型对象后,通过typeChecker.typeToString转换为可读的类型字符串。

此方案需处理文件变化同步、配置加载等细节,复杂度较高,但能获取更全面的类型元数据。

复杂场景处理说明

  • 箭头函数、函数调用等动态表达式:语言服务会自动推导返回值类型,直接用上述方法即可获取结果。
  • 匿名对象/数组:TypeScript会进行结构类型推导,返回的类型信息包含完整的结构定义。
  • JavaScript文件:只要有JSDoc类型注释,语言服务同样能正确识别类型。

内容的提问来源于stack exchange,提问作者Kyoshiro Kokujou Obscuritas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:55:20