如何让 VSCode Intellisense 与 ServiceNow Script Includes 一起使用?

How do you get VSCode Intellisense to work with ServiceNow Script Includes?

所以,我一直在为 VSCode 使用 ServiceNow Extension,虽然有很多问题,但除此之外它对我的目的来说效果很好。 然而,在处理更大范围的应用程序时,我 运行 遇到的一个问题是,Intellisense 不会从脚本包含中找到我当前正在处理的应用程序之外的函数和其他项目。

ServiceNow 中脚本包含的标准格式是:

var MyScriptInclude = Class.create();
MyScriptInclude.prototype = {
    initialize: function() {
    },
    /**
     * Do nothing function for illustration purposes
     * @param {*} a
     * @param {string} b
     * @param {number} c
     */
    fn_1: function(a, b, c) {
    },

    fn_n: function(d, e) {
    },
    
    type: 'MyScriptInclude'
};

因此,如果我要在 Visual Studio 代码中处理以下内容。
尝试从我的其他脚本 include 中引用 fn_1 时,Intellisense 不会提取任何信息。
它会在工具提示中显示的是 'any'

var MyOtherScriptInclude = Class.create();
MyOtherScriptInclude.prototype = {
    initialize: function() {
    },
    
    doSomethingWithOther: function() {
        var my_first_script_include = new MyScriptInclude();

        my_first_script_include.fn_1(); //<-- does not find any information about fn_1
    },
    
    type: 'MyOtherScriptInclude'
};

现在我明白了。 VSCode 不知道 Class.create() 返回什么。 ServiceNow 使用一个开箱即用的脚本包含名为 PrototypeServer 到 'build' 任何脚本包含你放入你的脚本。这就是它的样子:

var Class = {
  create: function() {
    return function() {
        /* This anonymous function will execute in the scope of the caller
           in interpreted mode. The initalize method is a utility we provide
           for giving a hook into the creation of a script include in scope.
           Many global script includes do not have an initialize function, and
           therefore we should only call this.initialize when present.
         */
        if (this.initialize)
            this.initialize.apply(this, arguments);
    };
  }
};

综上所述,我已经尝试了很多方法来尝试获取 Visual Studio 代码来尝试在这些脚本包含的 class 变量和原型对象之间建立联系.

我已经尝试记录(我所说的)class 变量并在原型中使用借出。这种方法在编译文档时正确地将原型和 class 相关联,但是,遗憾的是,它对 Intellisense 没有任何作用。

/**
 * My do nothing class for illustration purposes
 * @class
 */
var MyScriptInclude = Class.create();
MyScriptInclude.prototype = {
    /** @lends MyScriptInclude.prototype */
    /**
     * @constructs
     */
    initialize: function() { }
    //...
};

我也试过原型之外的借出

/** @lends MyScriptInclude.prototype */
MyScriptInclude.prototype = {};

我尝试将 class 变量定义为一个函数,因为 Class.create() returns 是一个匿名函数。

/**
 * My do nothing class for illustration purposes
 * @type {function}
 */
var MyScriptInclude = Class.create();
MyScriptInclude.prototype = { };

我还尝试将 PrototypeServer 全局脚本包含拉入我的工作区。 VSCode 将正确找到 Class.create() 函数,显示有关 Class.create() 的信息,并将 class 变量解释为函数...但仍然存在断开连接在 class 变量和原型函数之间,Intellisense 仍然显示 'any' 原型中的任何方法,找不到定义等

这无论如何都不会破坏交易,因为在 VSCode 中进行开发比在 ServiceNow 实例中进行开发要快得多。但是,如果我能弄清楚如何让它工作,那肯定会好得多。

这个问题的解决方法看似简单。 为 class 变量分配一个通用函数。 然后用 Class.create()

的结果覆盖泛型函数
/**
 * My do nothing class for illustration purposes
 */
 var MyScriptInclude = function(){}; //<--
 MyScriptInclude = Class.create();
 MyScriptInclude.prototype = {
     /** @lends DataSourceInterfaceFactory.prototype */
     
     /** @constructs */
     initialize: function() {},

     type: "MyScriptInclude"
 };

通过使用这种方法,您可以维护 ServiceNow 的 PrototypeServer 提供的开箱即用功能,无论它将来是否发生变化,智能感知将从您的其他地方获取此 class/script 包含的信息项目。

唯一不起作用的是 lends/constructs 定义,该定义指定应从初始化函数提供构造函数信息。当您使用新的智能感知实例化此 class 时,不会为您提供信息。
但如果你真的想要,你可以通过点遍历来初始化。
如果我发现如何正确 link 构建构造函数,我将更新此答案。否则,这是 95% 的解决方案。