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

如何在Monaco Editor中同时实现悬停提示与自动补全功能?

解决Monaco Editor自定义类提示与补全的方案

核心思路:结合类型定义与自定义补全增强

你提到的第三种方式(用类代码创建模型)其实可以通过补充规范JSDoc标注+轻量自定义补全增强实现需求,无需重复编写文档,同时兼顾悬停提示和带默认值的补全。

步骤1:完善JSDoc注释,让Monaco识别JS类型

纯JS下Monaco对类型的识别依赖标准JSDoc,调整你的类注释格式:

/**
 * MyClass
 * @class
 * @description This is my custom class.
 * @param {number} initialValue - 初始值
 */
class MyClass {
  /**
   * @type {number}
   */
  myProperty;

  /**
   * @type {string}
   */
  value;

  constructor(initialValue) {
    this.myProperty = initialValue;
  }

  /**
   * myMethod
   * @description This is a sample method.
   * @param {string} val - The value to store.
   */
  myMethod(val) {
    this.value = val;
  }
}

关键调整点:

  • 给类添加@class标签,给属性添加@type类型标注
  • 参数注释使用标准@param标签(而非@args,Monaco遵循标准JSDoc规范)
  • 在类顶层显式声明属性并标注类型,即使属性在构造函数中赋值

调整后Monaco就能识别c的类型为MyClass,自动提供属性/方法的悬停提示和基础补全。

步骤2:自定义补全提供器增强默认值插入

基于原生类型识别能力,写一个轻量补全提供器,仅针对需要默认值的方法做增强,无需重复维护类成员文档:

monaco.languages.registerCompletionItemProvider('javascript', {
  triggerCharacters: ['.'],
  provideCompletionItems(model, position) {
    const word = model.getWordUntilPosition(position);
    const range = new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn);
    
    // 判断当前是否为对象成员访问场景
    const lineContent = model.getLineContent(position.lineNumber);
    const prefix = lineContent.substring(0, position.column - 1);
    if (!prefix.endsWith('.')) return { suggestions: [] };

    // 复用Monaco原生类型补全结果,仅增强目标方法
    return monaco.editor.getModelLanguageService(model).doComplete(model, position).then(result => {
      const enhancedSuggestions = result.suggestions.map(suggestion => {
        if (suggestion.kind === monaco.languages.CompletionItemKind.Method && suggestion.label === 'myMethod') {
          return {
            ...suggestion,
            insertText: 'myMethod(${1:val})',
            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
          };
        }
        return suggestion;
      });
      return { suggestions: enhancedSuggestions };
    });
  }
});

这个提供器会复用原生类型补全的所有信息,仅给myMethod添加带占位符的默认值片段,避免重复劳动。

关于三种方式的兼容性

Monaco允许同时注册多种服务,原生类型服务(第三种方式)和自定义补全/悬停提供器可以共存,自定义提供器优先级更高,你可以用它增强原生功能,而非完全替代。

额外提示

  • 如果不想暴露类源码给编辑器,可以把类型定义抽成.d.ts文件,通过monaco.languages.typescript.javascriptDefaults.addExtraLib()注入到Monaco类型系统中,效果与直接引入类代码一致。
  • 属性的默认值补全也可以用相同逻辑,在提供器中判断属性类型后添加对应的默认值片段。

内容的提问来源于stack exchange,提问作者nucleon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 12:05:00