Can you not return values from async functions?

[ts] The return type of an async function or method must be the global Promise<T> type. [1064]

I’m getting this message after setting the return type in the asdocs but it seems to be working:

/**
 * Get artboard preferences
 * @param {Artboard} artboard
 * @returns {String}
 */
async function getPreferences(artboard) {
    ⋮
    return "test";
}

var preferences = await getPreferences(artboard);
log("Preferences: " + preferences); // "test"

Can you not return values from async functions? Is the TS warning incorrect? It seems to be working.

1 Like

The TS warning is correct, since you’ve specified the return type to be of the type String, but it in fact is a Promise<String> since the function is asynchronous.

Therefore, it is working since it’s only linting your Doc comment, but it warns you that the asynchronous function does – in fact – not return a string but a promise for a string (and therefore, things like autocompletion, linting etc. won’t work as expected).

Hope this helps,
Best,
Pablo

2 Likes

I would say the warning is not quiet correct.

If you have the following function:

/**
 * Get artboard preferences
 * @param {Artboard} artboard
 * @returns {String}
 */
async function getPreferences(artboard) {
    ⋮
    return "test";
}

And then call it like so:

 var value = await getPreferences(artboard);

It will return a string.

If you call it like this:

 var value = getPreferences(artboard);

It will return a promise of a string and maybe later on it will assign the string value.

So if it returns a promise or a string depends on the await keyword. But whatever.

Can I specify that the return type is String or Promise?

/**
 * Get artboard preferences
 * @param {Artboard} artboard
 * @returns {String|Promise}
 */
async function getPreferences(artboard) {
    return "test";
}

Is there a way to remove or hide this error in Visual Code?

1 Like

It actually always does return a Promise :wink:.

async/await are just syntax sugar for returning a promise and awaiting its resolution, but, under the hood, it’s still “Promise-land”.

Therefore, even though it doesn’t feel like it, you’re still dealing with promises. You can think of it as the order of operations being

await (getPreferences(artboard))

, meaning await gets applied to the Promise (it is a Promise) returned by the function.

When you’re using await, it’s really just a different syntax. That’s especially important as it has implications for performance as it (without optimizations in the interpreter, which to my knowledge usually don’t exist as that would be near impossible the way JS has to work) still builds callback-based callstacks.

Therefore, an async function always returns a Promise (since it’s short-hand for)

function xy() {
  return new Promise((resolve, reject) => ...)
}

and await allows you to easily handle this Promise, but the function still returns Promises. You’re just saving lines of code and increasing readability with syntax sugar :slightly_smiling_face: .

…maybe lol. I understand what you’re saying but when it is assigned a value after all the under the hood stuff it is assigning the string type in the end and not a promise.

So temporally it’s correct in the short term but not the long term.

So if we understand await and async then the VS code as linter / doc is not quite aware. Either way.

If I wrote my functions differently would it get rid of the error.

/**
 * Get artboard preferences
 * @param {Artboard} artboard
 * @returns {String}
 */
async function getPreferences(artboard) {
    return new Promise( "test" ); 
}
1 Like

It is, however, factually wrong (even if VSCode doesn’t show an error for this, which is, at the least, questionable :wink:).

The function returns a Promise. This, the doc comment denotes. Whether you await this promise, throw it away or whatever is the same to the function and what it returns (a function should, after all, be reusable and not care about what you do with the return value). Therefore, the doc comment should state that the function returns a Promise, since this is what it returns.

Yes, you are assigning a string type (the await “operation”, in a way, converts it to a string), and thus, value is of the type string. The return value, however, is not and documenting it to be of this type is quite simply (with all due respect) wrong. If that works for you: great. But that doesn’t change the fact that it’s not what the function returns :stuck_out_tongue_winking_eye:

After all, if a function returns a number that represents a number of seconds, it still returns a number. It doesn’t (and shouldn’t) care if you later use it as a string appending " seconds" to it, it returns a number (which is documented to be of that type and represent the number of seconds).

Just because you later use it as something different doesn’t mean that’s what (in a logical sense) gets returned :wink: