Using TypeScript will result in errors when attempting to use the Promise object and the Awaited keyword

In this example, I am trying to ensure that the function foo does not accept a Promise as an argument, but any other type should be acceptable.

export {}

function foo<T>(arg: T extends Promise<unknown> ? never : T) {
  console.log(arg);
}

async function bar<T>(arg: Promise<T>) {
  foo(await arg); // Why is this causing an error?
}

async function baz(arg: Promise<number>) {
  foo(await arg); // This works fine!
}

foo(await Promise.resolve(1)); // No issues here

foo(1); // All good

foo(Promise.resolve(1)); // This should give an error, as expected

When looking at the error in the bar function:

Argument of type 'Awaited<T>' is not assignable
to parameter of type 'T extends Promise<unknown> ? never : T'.

What exactly sets apart T from Awaited<T>?

Is there a solution to make this work correctly, especially when utilizing await with generics?

Answer №1

When the type T extends Promise<unknown>, it implies that the argument must be of type never. However, if we are unaware of the actual type of T within the function bar, ensuring the correctness of the type passed to foo becomes uncertain.

In essence, it is plausible to provide a parameter of type

Promise<Promise<any>>
to bar, wherein technically T would represent a Promise.

Nonetheless, since await handles resolving nested promises, post-await operation confirms that the resolved value cannot be a Promise. Regrettably, the Typescript compiler fails to recognize this fact.

Hence, it is feasible to establish a generic type for this argument and securely cast it after await.

type NotPromise<T> = T extends Promise<unknown> ? never: T;

function foo<T>(arg: NotPromise<T>) {
  console.log(arg);
}

async function bar<T>(arg: Promise<T>) {
  foo((await arg) as NotPromise<T>);
}

For a functional demonstration, visit: https://stackblitz.com/edit/typescript-h2izuv?file=index.ts

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The sequence of operations when assigning in Typescript with || and utilizing the array .find method

I need to ensure that the operations in my assignment are happening in a specific sequence. As far as I can tell, it should be following the order listed below. However, I have not been able to locate any documentation on TypeScript that definitively confi ...

Incorporate a personalized Material UI checkbox within a column of the Material React table

Starting out with React, I decided to incorporate Material React Table v2 into my project. My goal is to include a Material UI checkbox that accurately represents the 'Is Active' data in a disabled state. Despite numerous attempts, I have not bee ...

Guide on incorporating Bootstrap 4 beta.2 into an Angular 4 project

After attempting to install Bootstrap 4 version beta.2 along with its dependencies (jquery and popper.js), I encountered a strange problem. A SyntaxError message kept appearing in the console, specifically stating "SyntaxError: export declarations may only ...

Utilizing a powerful combination of Angular 5, PrimeNG charts, Spring Boot, and JHipster

I am facing an issue with creating charts using PrimeNG. The main challenge I'm encountering is the conversion of data from a REST API in Angular 5 (TypeScript) and retrieving the list of measurements from the API. I have an endpoint that returns my m ...

What could be causing the conditional div to malfunction in Angular?

There are three conditional div elements on a page, each meant to be displayed based on specific conditions. <div *ngIf="isAvailable=='true'"> <form> <div class="form-group"> <label for ...

React component stuck in endless loop due to Intersection Observer

My goal is to track the visibility of 3 elements and update state each time one of them becomes visible. Despite trying various methods like other libraries, useMemo, useCallback, refs, etc., I still face challenges with my latest code: Endless loop scenar ...

Issue with custom validator in Angular 6: setTimeout function not functioning as expected

Currently, I am in the process of following a tutorial to implement Asynchronous validation in Angular. The goal is to create a custom validator named shouldBeUnique that will be triggered after a 2-second delay. To achieve this, I have utilized the setTim ...

Is there something I'm missing? The action buttons cannot be displayed on a preview of the event

Currently in the process of developing an angular application featuring a calendar component to showcase events, I opted to utilize angular-calendar for the visual representation. While exploring the month view functionality, I encountered an issue where t ...

Instantiate a fresh object using the new keyword followed by the Class constructor, and if desired,

I'm looking for a class that I can easily create new instances from and optionally assign properties using the constructor. For instance: class Person { name: string; age: number; constructor(props: {name?: string, age?: number}) { this.nam ...

Attempting to search for an item by its id within a local json file using Angular

I have a local JSON file containing Kitchen types. I created the KitchenTypesService with two functions inside, GET and FIND(ID). The GET function is working fine, but the FIND function is not working and displaying an error "ERROR TypeError: Unable to lif ...

execute the function once the filereader has completed reading the files

submitTCtoDB(updateTagForm:any){ for(let i=0;i<this.selectedFileList.length;i++){ let file=this.selectedFileList[i]; this.readFile(file, function(selectedFileList) { this.submitTC(updateTagForm,selectedFileList); }); } } } ...

Unlock the potential of Power BI with this step-by-step guide on enhancing the Circle Card visual by incorporating unique formatting

Power BI Tutorial: Adding Formatting Options to the Circle Card Visual After completing step 8, I copied the code into my VS Code and encountered 2 error messages: Error message: "import VisualSettings - Module '"./settings"' has no e ...

Instructions for creating a function that can receive an array of objects containing a particular data type for the value associated with the key K

Seeking guidance on how to define a specific signature for a function that accepts an array of objects and 3 column names as input: function customFunction<T, K extends keyof T>( dataset: T[], propertyOne: K, propertyTwo: K, propertyThird: K ...

Is there a problem with Angular2 using TypeScript?

Currently, I am in the process of setting up my machine for Angular development by following the guidelines provided on https://angular.io/docs/ts/latest/quickstart.html As I proceeded to run "npm start" to launch my site, I encountered an issue with the ...

What is the best way to set up a variable in Typescript that will be assigned the value of an asynchronous request once it is completed?

As a newcomer to typescript, I encountered an issue that hadn't occurred in my previous project. It appears that declaring a variable before an API request inside a try-catch block leads to typescript errors when attempting to use this variable after ...

Improving the process of class initialization in Angular 4 using TypeScript

Is there a more efficient method to initialize an inner class within an outer class in Angular 4? Suppose we have an outer class named ProductsModel that includes ProductsListModel. We need to send the ProductId string array as part of a server-side reque ...

How can I showcase array elements using checkboxes in an Ionic framework?

Having a simple issue where I am fetching data from firebase into an array list and need to display it with checkboxes. Can you assist me in this? The 'tasks' array fetched from firebase is available, just looking to show it within checkboxes. Th ...

Several values are not equal to the typeorem parameter

I am looking for a way to create a Typeorm query that will return results similar to the following SQL statement: SELECT * FROM Users WHERE id <> 3 and id <> 8 and id <> 23; Any suggestions on how I can achieve this? Thank you! ...

Building a personalized React component poses challenges when working with MUI REACT interfaces

I am looking to develop a unique component that will display two different elements, an icon, and a title. However, I seem to be encountering errors from TypeScript regarding the declaration of my interface. The error message reads: Property 'map&apos ...

Unexpected token { in Fuse-Box when using Typescript

Here's the beginning of my fuse.ts file import { CSSPluginOptions } from 'fuse-box/plugins/stylesheet/CSSplugin'; import { argv } from 'yargs'; import * as path from 'path'; import { CSSPlugin, CSSResourcePlugin, Env ...