简体   繁体   中英

Asynchronus Intellisense in Visual Studio Code | NodeJS

I often write modules that are asynchronous, and due to their asynchronous nature I will require, resolve, and then assign these modules during some initialization code. For example:

var asynchronousModule;


function doSomethingUsingMyLoadedModule() {
    // Ideally intellisense would be able to do its thing for asynchronousModule right here
    asynchronousModule._doSomething();
}


// initializer
(async () => {
    asynchrousModule = await require('my-custom-async-module');
})();

However, because asynchronousModule isn't assigned until after the doSomethingUsingMyLoadedModule function is declared, intellisense can't auto-complete/auto-populate asynchronousModule within that function.

So I'm wondering if there's a way to explicitly tell intellisense to prematurely assign a value to our variable at declaration time, using inline-comments or some such. For example, something like this on the first line:

var asynchronousModule; // vsc-intellisense assign-async-import my-custom-async-module

That'd be awesome, but probably wishful thinking. However, perhaps there's still some other way of leveraging intellisense for async modules without having to wrap my entire file in an async function? By that I mean re-writing my code to something like this:

(async () => {
    const asynchrousModule = await require('my-custom-async-module');

    function doSomethingUsingMyLoadedModule() {
        asynchrousModule._doSomething();
    }
})();

While this would allow intellisense to work, and it actually looks nice in this example, I really don't like having the contents of an entire file tabbed over, especially as files get bigger, so it's not my ideal solution.

Just try this

const asynchrousModule = require('my-custom-async-module');

function doSomethingUsingMyLoadedModule() {
    asynchrousModule._doSomething();
}

When I first asked this question, I was a naïve developer who didn't understand how much TypeScript I was actually using when writing JSDoc-esque syntax for IntelliSense in my editor. But now, as a much wiser developer a month and change later, I have an answer to this.

Note that I'm not necessarily saying it's a great idea to override your module's export object with a promise, but doing so worked for me in the past, and at the very least I can use the following to provide accurate IntelliSense for legacy code:

/**
 * @template T
 * @typedef  {T extends Promise<infer Value> ? Value : T} PromiseValue
 */

/** @type {PromiseValue<import('my-custom-async-module')>} */
var asynchronousModule;

The @typedef tag declares the type PromiseValue which we use to extract what a promise resolves to. Then with the @type tag, we import the asynchronous module and wrap it in our PromiseValue utility to extract its resolved object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM