Skip to content

Promise#finally's callback doesn't accept Promise<void> callback, unlike Promise#then #44980

@blair

Description

@blair

lib Update Request

Configuration Check

My compilation target is ES2018 and my lib is the default.

Missing / Incorrect Definition

Promise#finally

Sample Code

export async function closeDbConnection(): Promise<void> {
    return Promise.resolve();
}

Promise
    .resolve()
    .finally(closeDbConnection);

The suggested change is changing lib/lib.es2018.promise.d.ts from

finally(onfinally?: (() => void) | undefined | null): Promise<T>

to

finally(onfinally?: (() => void | PromiseLike<void>) | undefined | null): Promise<T>

The current typing, without the PromiseLike, suggests that the runtime will not wait for the onfinally callback to resolve if it's a Promise, however, it does. This can be seen in the console when test changes from pending to 123.

> test = Promise.resolve(123).finally(() => new Promise(resolve => setTimeout(resolve, 5000)))
Promise { <pending> }
> test
Promise { <pending> }
> test
Promise { <pending> }
> test
Promise { <pending> }
> test
Promise { <pending> }
> test
Promise { <pending> }
> test
Promise { <pending> }
> test
Promise { 123 }

Additionally, for consistency between #then and #finally, the current onfinally definition doesn't match Promise#then in lib/lib.es5.d.ts where onfullfilled returns TResult1 | PromiseLike<TResult1>.

interface Promise<T> {
    /**
     * Attaches callbacks for the resolution and/or rejection of the Promise.
     * @param onfulfilled The callback to execute when the Promise is resolved.
     * @param onrejected The callback to execute when the Promise is rejected.
     * @returns A Promise for the completion of which ever callback is executed.
     */
    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;

Documentation Link

https://tc39.es/ecma262/#sec-promise.prototype.finally

Suggests that .finally() is implemented similar to .then(result => Promise.resolve(onFinally()).then(result)).

Metadata

Metadata

Assignees

No one assigned

    Labels

    ExternalRelates to another program, environment, or user action which we cannot control.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions