Skip to content

Support promise-like types in contextual return type of async function - #27256

Closed
Ron Buckton (rbuckton) wants to merge 3 commits into
release-3.1from
fix24629
Closed

Support promise-like types in contextual return type of async function#27256
Ron Buckton (rbuckton) wants to merge 3 commits into
release-3.1from
fix24629

Conversation

@rbuckton

@rbuckton Ron Buckton (rbuckton) commented Sep 21, 2018

Copy link
Copy Markdown
Contributor

This changes the contextual type we use for a return expression in an async function. Prior to this change, we would infer {} for the type argument to Promise below:

interface Obj { key: "value"; }

function fn1(): Promise<Obj> {
    // ok: return expression is contextually typed to 'Promise<Obj>' so 'T' in 'Promise<T>' 
    // is contextually typed to 'Obj'.
    return new Promise(resolve => { resolve({ key: "value" }); });
}

async function fn2(): Promise<Obj> {
    // ok: return expression is contextually typed to 'Obj'.
    return { key: "value" }; 
}

async function fn3(): Promise<Obj> {
    // error: '{}' is not assignable to type 'Obj'.
    // return expression is contextually typed to 'Obj' so 'T' in 'Promise<T>' is not
    // contextually typed and becomes '{}'
    return new Promise(resolve => { resolve({ key: "value" }); });
}

This is because we use the "awaited type" Obj for the return type Promise<Obj> as the contextual type. With this change, we use Obj | PromiseLike<Obj> as the contextual type:

interface Obj { key: "value"; }

function fn1(): Promise<Obj> {
    // ok: return expression is contextually typed to 'Promise<Obj>' so 'T' in 'Promise<T>' 
    // is contextually typed to 'Obj'.
    return new Promise(resolve => { resolve({ key: "value" }); });
}

async function fn2(): Promise<Obj> {
    // ok: return expression is contextually typed to 'Obj | PromiseLike<Obj>'.
    return { key: "value" }; 
}

async function fn3(): Promise<Obj> {
    // ok: return expression is contextually typed to 'Obj | PromiseLike<Obj>' so 'T' in 
    // 'Promise<T>' is contextually typed to 'Obj'
    return new Promise(resolve => { resolve({ key: "value" }); });
}

Fixes #24629, #27001

@rbuckton

Copy link
Copy Markdown
Contributor Author

Wesley Wigham (@weswigham): I opted to just continue using PromiseLike as opposed to some other construct for the time being.

@DanielRosenwasser

Copy link
Copy Markdown
Member

Does this fix #27001 too?

@rbuckton

Copy link
Copy Markdown
Contributor Author

Daniel Rosenwasser (@DanielRosenwasser): I don't think it does, but I will check that tomorrow.

@rbuckton

Copy link
Copy Markdown
Contributor Author

Daniel Rosenwasser (@DanielRosenwasser): It does now, the fix for #27001 was easy to accomplish with the changes in this PR since you need the same behavior (union the awaited type with a PromiseLike of the awaited type).

@rbuckton

Copy link
Copy Markdown
Contributor Author

This change is postponed to 3.2, you can find the PR against master here: #27270

@rbuckton
Ron Buckton (rbuckton) deleted the fix24629 branch September 21, 2018 17:46
@microsoft Microsoft (microsoft) locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants