Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference TypeScript definition file from HTML `<script>` with VS Code

I am able to use JSDoc in a script tag in HTML but am not able to reference a type definition file (.d.ts). I'm using VS Code. Is this possible and if so how do I do it? Here's some example code below:

The tsconfig.json file (I'm not sure how to quite use this in my tests, it doesn't seem to be needed.):

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

Attempt 1:

In types/MyLib/index.d.ts:

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

In the JS file index.js and works fine:

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

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

In the HTML file (none of these work) 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>

Attempt 2:

In types/MyLib/index2.d.ts:

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

In the JS file index2.js and works fine:

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

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

In the HTML file (none of these work) 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>
like image 478
Jon49 Avatar asked Oct 26 '25 15:10

Jon49


1 Answers

I did some research, dig into source code and find out the language service used for embedded <script> inside HTML is entirely different from the one used for standalone .js/.ts file.

Check the above link if you're interested. As you would see, it's another builtin extension "html-language-features" as opposed to "typescript-language-features". So first of all, it's impossible for the two to behave the same. Second of all, the ts language service instance used are intentionally created with a fixed and simplified ts.compilerOptions, with no setting API exposed to user to customize it.

Your feature request is actually a long standing one, see #26338, dates back to 2017, but vscode team seems reluctant to respond.

So, dead end here...Not possible with the official extension.

Possible solution is to fork the html-language-features project to make a custom build, so to smuggle in the features you want. You can disable the builtin extension and replace it with your custom build.

As of what code to modify, I'm not expert of the TS programming API, but I can refer you to this @shuaihuGao guy's patch, found in the above github issue. The patch adds a setting option html.libDefinitionFiles to take in a list of .d.ts files to be included when validating embedded JS script.

Not entirely what you ask, but a nice workaround nonetheless. You might want to try it out, download link here.

like image 189
hackape Avatar answered Oct 29 '25 06:10

hackape