microsoft / microsoft/TypeScript

async function drops `Awaited<Type>`

Abierto
#56,083 0 comentarios 0 reacciones 1 asignado Ver en GitHub

@rbuckton ya está trabajando en esto.

Desde el 12/10/2023.

Needs Investigation
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
1 d 19 h
PR fusionados (30 d)
117

Descripción

🔎 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).

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.