Skip to content

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

Merged
rbuckton merged 3 commits intomasterfrom
fix24570-2
Sep 21, 2018
Merged

Support promise-like types in contextual return type of async function#27270
rbuckton merged 3 commits intomasterfrom
fix24570-2

Conversation

@rbuckton
Copy link
Copy Markdown
Contributor

@rbuckton rbuckton commented Sep 21, 2018

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 rbuckton added this to the TypeScript 3.2 milestone Sep 21, 2018
@rbuckton rbuckton changed the title Fix24570 2 Support promise-like types in contextual return type of async function Sep 21, 2018
@rbuckton rbuckton merged commit 9e4e569 into master Sep 21, 2018
@rbuckton rbuckton deleted the fix24570-2 branch September 21, 2018 17:52
@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