Skip to content

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

Merged
Ron Buckton (rbuckton) merged 3 commits into
masterfrom
fix24570-2
Sep 21, 2018
Merged

Support promise-like types in contextual return type of async function#27270
Ron Buckton (rbuckton) merged 3 commits into
masterfrom
fix24570-2

Conversation

@rbuckton

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

Copy link
Copy Markdown
Contributor

NOTE: This is the same change in #27256 except this targets "master"

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

edit: There is a typo in the branch name (fix24570-2) which incorrectly mentions a different issue, the commits in this PR do correctly address #24629 and #27001.

@rbuckton
Ron Buckton (rbuckton) merged commit 9e4e569 into master Sep 21, 2018
@rbuckton
Ron Buckton (rbuckton) deleted the fix24570-2 branch September 21, 2018 17:52
@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.

Marking a function async changes how return type annotation effects type inference

2 participants