microsoft / microsoft/TypeScript

async function drops `Awaited<Type>`

Aperta
#56,083 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@rbuckton ci sta già lavorando.

Dal 12/10/2023.

Needs Investigation
Lingua principale
Go
Stelle
111k
Fork
14.4k
Merge medio
1g 19h
PR unite (30g)
117

Descrizione

🔎 Search Terms

async function drops Awaited
Awaited swallowed in async
Awaited removed

🕗 Version & Regression Information
  • This is the behavior in every TS version I tried, started occurring since TS v 4.5.5 when the Awaited was introduced.
⏯ Playground Link

https://www.typescriptlang.org/play?ts=4.5.5#code/PTAEGcEsHMDsEMAuBXATgU3KA9gM1IgBbqi7KwDGik2sW8GoF2ADpOgCamrYC2oABR69I4dADpU8CugBQsspWq1QUmQH1IHdLGqIAnuuwBrADwAVUOgAeiHRywZ4HWgBt9ocsdjYA7rABtAF1QAB9QYIA+AApQADd4V2RMAC5QcwBKNKE+UXRTAEFfeEg7DgsA2GReACN0VCDIyNAAb1lQDtV0FFRYQWE8yWl0aISkzAyOkFAAeQBpABpQLR09D0UqGj7fbFRjLAArZHBEUkhYOQBfeQ3lPrV0dV8pFhZOTVh1eHB9SnUfRBGMyWGx2WAOLrONweLw+fzBMIRRqxMbJcBpTLZAZiQrFUqcCpVWr1RrNNqdJi0E6gb6-CgAdReb1QoAAvDSfpRQNFJqyye0KZ1mHRTg82TS8acciIxEMZKNEmiMgLBaBpsLqQ80kUSmVCdU6g1moL5ksiKICPo3sssDY3lROCrBRgevdhhSndcKeqqadaZRGfBXvU0jy2c1pXl9cSjYLzVgLQDZotQE7pr4SHb0FRLdaw3z+rkcTr8eVzJUDSSmksashTkQSAADEt6yKN0DFLAcHjBjhLZmEIPgAD88gpLrQfX9DKZ9R5abA9R4qBSC-SVpIAHJIzjy0TDY1NzbQEnvlA4PAaq4SIhsLmtzv8i2CXvK0bIpvxGvzBvQJvXzGQRHom2B+uA54IFeN53gY1qbs+ZYVoBH7iNEABMADMaFocqlxAA

💻 Code
// signatures of the functions are copied from Promise.race

function race_identity_ok<T extends readonly unknown[] | []>( values: T): Promise<Awaited<T[number]>> {
    return Promise.race(values)  // OK, identity function works just fine
}

function race_wrapped_in_async_not_ok<T extends readonly unknown[] | []>( values: T): Promise<Awaited<T[number]>> {
    const asyncWrapper = async () => {
        const race = await Promise.race(values)
        // const race: Awaited<T[number]>      OK, this type is expected
        return race    
    }
    // const asyncWrapper: () => Promise<T[number]>     this is not OK, 
    // we expect type () => Promise<Awaited<T[number]>>, but the `Awaited<>` was dropped, perhaps?

    return asyncWrapper()
    // error:
    // Type 'Promise<T[number]>' is not assignable to type 'Promise<Awaited<T[number]>>'.
    // Type 'T[number]' is not assignable to type 'Awaited<T[number]>'.(2322)
}```


### 🙁 Actual behavior

The `Awaited<Type>` is dropped from the return type of the function `asyncWrapper`, but it should not be (at least as I can tell).


### 🙂 Expected behavior

The `Awaited` should not be dropped.
I believe so because I assume the `Awaited` in the `Promise.race` signature is of crucial importance, as it denotes that if type `T` is a thenable (or `PromiseLike`, if you like), it is unwrapped in the return type.
Wrapping the `Promise.race` in `async` function (`asyncWrapper`) looses the unwrapping semantics, in my opinion.



### Additional information about the issue

The issue might seem artificial, however, this is the minimalist example I came up with. In our codebase, the issue is convoluted because we replace `PromiseLike` with [CancellablePromise](https://github.com/srmagura/real-cancellable-promise). We need the async function wrapper to correctly deduce return type (and keep the `Awaited`), so that the return type of `Promise.race` is perserved when fed through the [buildCancellablePromise](https://github.com/srmagura/real-cancellable-promise#combine-multiple-api-calls-into-a-single-async-flow).

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.