使用 VS Code 从 HTML `<script>` 引用 TypeScript 定义文件

Posted

技术标签:

【中文标题】使用 VS Code 从 HTML `<script>` 引用 TypeScript 定义文件【英文标题】:Reference TypeScript definition file from HTML `<script>` with VS Code 【发布时间】:2021-01-05 23:12:05 【问题描述】:

我可以在 htmlscript 标记中使用 JSDoc,但无法引用类型定义文件 (.d.ts)。我正在使用VS Code。这可能吗?如果可以,我该怎么做?下面是一些示例代码:

tsconfig.json 文件(我不确定如何在测试中完全使用它,似乎不需要它。):


    "compilerOptions": 
        "baseUrl": ".",
        "paths": 
            "myLib": ["types/MyLib/index.d.ts"],
            "myLib2": ["types/MyLib/index2.d.ts"]
        
    

尝试 1:

types/MyLib/index.d.ts:

declare namespace myLib 
  function makeGreeting(s: string): string
  let numberOfGreetings: number

在 JS 文件中 index.js 并且工作正常:

/// <reference path="./types/MyLib/index.d.ts" />
// @ts-check

var result = myLib.makeGreeting("Cheese")
console.log(result)

在 HTML 文件中(这些都不起作用)index.html:

<script>
    /// <reference path="./types/MyLib/index.d.ts" />
    // @ts-check
    var result = myLib.makeGreeting("Cheese")
</script>

<script>
    // @ts-check
    /** @type import("./types/MyLib/index").myLib */
    var myLib = Window.myLib
    var result = myLib.makeGreeting("Orange")
</script>

<script>
    // @ts-check
    /** @typedef import("./types/MyLib/index").myLib myLib */
    /** @type myLib */
    var myLib = Window.myLib
    var result = myLib.makeGreeting("Orange")
</script>

尝试 2:

types/MyLib/index2.d.ts:

export declare module myLib 
  export function makeGreeting(s: string): string

在 JS 文件 index2.js 中并且工作正常:

/// <reference path="./types/MyLib/index2.d.ts" />
// @ts-check

var result = myLib.makeGreeting("Cheese")
console.log(result)

在 HTML 文件中(这些都不起作用)index2.html:

<script>
    /// <reference path="./types/MyLib/index2.d.ts" />
    // @ts-check
    var result = myLib.makeGreeting("Cheese")
</script>

<script>
    // @ts-check
    /** @type import("./types/MyLib/index2").myLib */
    var myLib = Window.myLib
    var result = myLib.makeGreeting("Orange")
</script>

<script>
    // @ts-check
    /** @typedef import("./types/MyLib/index2").myLib myLib */
    /** @type myLib */
    var myLib = Window.myLib
    var result = myLib.makeGreeting("Orange")
</script>

【问题讨论】:

这取决于您的 IDE。由于这些文件不是 javascript 文件,而是在标签中嵌入了 JavaScript 的 HTML 文件,因此您的 IDE 的 HTML 语言服务需要与 TypeScript 语言服务(或其他具有相同功能的服务)进行互操作,并使用它来处理脚本标签内容。跨度> 哦,是的,我忘记输入我正在使用的 IDE。我正在使用 VS 代码。我会更新问题。 因为它适用于 JavaScript 文件,但不适用于脚本标签,您需要一个 HTML 插件,处理脚本按您想要的方式阻止,但我不知道这样的插件是否可用.无论如何,在脚本标签中写多行是一种不好的做法 这是一个有趣的小项目,我正在处理我从服务人员流式传输 HTML 并调用 IndexedDB 来获取数据。所以,我想要类似于 Svelte 工作方式的东西,我可以将 HTML 和 JavaScript 放在同一个文件中,以保持其更具凝聚力。但我实际上在构建时将 HTML/JS 解析为仅 JS 的文件。所以,我想要 TypeScript 定义文件的原因是因为它比简单的应用程序更复杂。但是带有 JSDoc 的 TypeScript(类型检查器)在脚本标签中工作正常,但由于某种原因不允许我导入外部类型。 啊,我明白你的意思了。我认为 JSDoc 类型在标签中根本不适合你。我认为您可以让它们工作,并且它可能与 tsconfig.json 有关。稍后我会尝试查看它。 【参考方案1】:

我做了一些研究,深入了解source code 并发现用于在 HTML 中嵌入 &lt;script&gt;语言服务与用于独立 .js/.ts 文件的完全不同。 p>

如果您有兴趣,请查看上面的链接。如您所见,它是另一个内置扩展 "html-language-features",而不是 "typescript-language-features"。所以首先,两者的行为不可能相同。其次,使用的 ts 语言服务 实例是有意使用固定和简化的ts.compilerOptions 创建的,没有向用户公开设置 API 来自定义它。

您的功能请求实际上是一个长期存在的请求,请参阅 #26338,可以追溯到 2017 年,但 vscode 团队似乎不愿回应。

所以,死路一条……官方扩展不可能。

可能的解决方案是 fork html-language-features 项目以进行自定义构建,以便走私您想要的功能。您可以禁用内置扩展并将其替换为您的自定义构建。

至于要修改什么代码,我不是 TS 编程 API 的专家,但我可以参考这个 @shuaihuGao 家伙的 patch,在上述 github 问题中找到。该补丁添加了一个设置选项html.libDefinitionFiles 以获取在验证嵌入式JS 脚本时要包含的.d.ts 文件列表。

不完全是您所要求的,但仍然是一个不错的解决方法。您可能想尝试一下,download link here。

【讨论】:

以上是关于使用 VS Code 从 HTML `<script>` 引用 TypeScript 定义文件的主要内容,如果未能解决你的问题,请参考以下文章

Django 不会在 VS Code 编辑器中解析静态文件的路径

Ubuntu下使用VS Code创建Spring Boot工程

Windows VS Code remote-SSH ubuntu

VS Code php 标签自动完成

在 VS Code 中保存时关闭自动关闭的 HTML 标签?

VS Code 中 HTML 文档注释 js 语句异常