The promise of returning a number is not compatible with a standalone number

I am currently working on a function that retrieves a number from a promise. The function getActualId is called from chrome.local.storage and returns a promise:

function getActualId(){
    return new Promise(function (resolve) {
        chrome.storage.sync.get({
            userId: true
        }, function (userId) {
            resolve(userId.userId);
        });
    });
}

While this function successfully fetches the desired value, I am facing an issue when calling it from another function. Despite specifying that the getId function should return a Promise<number>, it still returns a promise instead.

async function getId(){
    let id:number = 0;
    await getActualId().then( function(userid:number){
        id =  userid;
    })
    return id
}

How can I obtain the actual value of id from getId rather than a promise<number>?

Answer №1

Rarely do you utilize the then keyword within an async function.¹ The primary benefit of utilizing async functions is the ability to employ await instead. In this particular scenario, you should assign the outcome of await getActualId() to the variable id:

async function fetchId(){
    let id:number = await getActualId();
    return id;
}

(Although it's not entirely clear why such a function would be necessary, as it appears to only serve as a wrapper for getActualId.)

An issue exists with the getActualId function, however, which can be resolved by defining the return type: getActualId is currently lacking a return type annotation, hence it implicitly returns Promise<any>. If it should be returning Promise<number>, then that specification needs to be indicated:

function getActualId(): Promise<number> {
    return new Promise(function (resolve) {
        chrome.storage.sync.get({
            userId: true
        }, function (userId) {
            resolve(userId.userId);
        });
    });
}

View example in the online playground here:

function getActualId(): Promise<number> {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(Math.floor(Math.random() * 100));
        }, 100);
    });
}
async function fetchId() {
    let id = await getActualId();
    return id;
}

If you hover over the variable id inside the fetchId function, TypeScript will recognize it as a number based on the signature of getActualId, eliminating the need for a redundant type annotation.


¹ When I say "rarely," I truly mean exceedingly rarely. One possible scenario where you might use it is if you have multiple operations to execute concurrently (and are employing Promise.all) and you need to manipulate the result of one operation. In that case, you could potentially do something like this:

const [first, second, third] = await Promise.all([
   firstOp(),
   secondOp().then(value => value.toUpperCase()),
   thirdOp()
]);

This approach allows the execution of thirdOp to proceed immediately without being delayed by the completion of secondOp, as would occur if await was used on secondOp.

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

I am puzzled as to why my function's return type transforms into a promise when I interact with the cell.value or use console.log

Recently, I embarked on the journey of coding a validation process for my Excel Sheet. To keep the code concise, I implemented it in a straightforward manner. Here is a snippet of my source code: function main(workbook: ExcelScript.Workbook) { console. ...

What is the best way to write a function in typescript that verifies whether the argument extends a type argument and then returns the argument?

I need to create a function that checks if the argument's type extends a specific type variable and then returns the argument. Something like this: declare function checkType<T, X extends T>(argument: X): X However, TypeScript gives an error wh ...

How can I achieve a result using a floating label in a .ts file?

I'm facing a simple issue that I can't seem to figure out. The problem is with a floating label in my HTML file, as shown below: <ion-list> <ion-item> <ion-label floating >Username</ion-la ...

What made the "in" operator not the best choice in this situation?

When I set out to create a type that represents the values of a given object type, I initially came up with this: type Book = { name:string, year:number, author:string } // expected result "string" | "number" type ValueOf<T ex ...

The 'HTMLDivElement' type does not include the property 'prepend' in Typescript

When working with a typescript method, the following code snippet is used: some_existing_div.prepend(some_new_div) This may result in an error message: [ts] Property 'prepend' does not exist on type 'HTMLDivElement'. However, despi ...

Obtaining a string union value dynamically during execution

Question 1: Exploring a component library, material-ui, which offers interfaces and types for customizing the css class values of each component. For the Select component, they define a type as a combination of string literals type SelectClassKey = " ...

What could be causing the Uncaught Error to persist even after using .catch()?

Check out this code snippet: function pause(ms:number) { return new Promise((resolve:any,reject:any) => setTimeout(resolve,ms)) } async function throwError(): Promise<void> { await pause(2000) console.log("error throw") throw new ...

I possess both a minimum and maximum number; how can I effectively create an array containing n random numbers within

Given a minimum number of 10.5 and a maximum number of 29.75, the task is to generate an array within these two ranges with a specific length denoted by 'n'. While the function for generating the array is provided below, it is important to calcul ...

Mastering the art of leveraging generics in conjunction with ngrx actions

Currently, I am in the process of developing an Angular 7 application that utilizes the NGRX store. In our application, we have numerous entities, each with its own dedicated list view. I decided to explore using generics with the NGRX store to avoid writi ...

Unable to delete event listeners from the browser's Document Object Model

Issue at hand involves two methods; one for initializing event listeners and the other for deleting them. Upon deletion, successful messages in the console confirm removal from the component's listener array. However, post-deletion, interactions with ...

How come the splice method is changing the value of the original object?

There's something strange happening with this code I'm trying out. Code: const x = [{ a: 'alpha', b: 'beta' }, { a: 'gamma' }]; const y = x[0]; y.a = 'delta'; x.splice(1, 0, y) console.log(x) Output: [ ...

An Unexpected Typescript Error Occurred While Creating an RxCollection With RxDB

I'm new to RxDB and I've come across a strange Typescript error in my Electron project. Here are the relevant parts of my code: import RxDB, { RxCollection, RxDatabase } from "rxdb"; RxDB.plugin(require("pouchdb-adapter-idb") ...

Definition of TypeScript for caching middleware in Express

I recently came across a helpful Medium post that inspired me to create an express middleware function for caching the response. However, I'm facing some challenges while trying to implement it in typescript. Specifically, I am struggling to identify ...

The functionality of NgbModal in ng-bootstrap is experiencing issues and becoming unresponsive in ng-bootstrap version 15 and Angular version 16

Currently, I am in the process of upgrading my Angular app from version 15 to version 16. Following the documentation, I have updated the @ng-bootstrap/ng-bootstrap package to version 15. However, after this update, I am facing issues with the NgbModals no ...

Iterate over Observable data, add to an array, and showcase all outcomes from the array in typescript

Is there a way to iterate through the data I've subscribed to as an Observable, store it in an array, and then display the entire dataset from the array rather than just page by page? Currently, my code only shows data from each individual "page" but ...

After deploying to Heroku, cal-heatmap encounters errors despite functioning correctly in a local environment

I successfully implemented a cal-heatmap instance in my Angular 2 (angular-cli) project locally, but when I deployed the project to Heroku, I encountered some errors that prevent the cal-heatmap from displaying. https://i.stack.imgur.com/8gY90.png The er ...

Repeating promises in Node.js through recursive execution

Here is a function that allows you to create a new folder on the server using xmlrpc: var createFolder = function(folder_name) { var defer = Q.defer(); client.methodCall('create_folder', [sessionID, folder_name], function(err, resp) { if ...

Is there a way to verify if a component contains a child node with the tag <template></template>?

Consider the scenario with MyComponent: <div [my-component]="'text'"></div> Within the code, I have access to this.viewContainerRef, which refers to the DOM node itself (<div>). However, for customization purposes, a user mig ...

Visual Studio - TypeScript project synchronization issue

Currently using the 2015 version of Visual Studio Community, I am facing an issue while working on a typescript project. Whenever I make modifications to the code, debug it, and save it using ctrl + s followed by refreshing the browser with ctrl + r, the c ...

What is the best way for a function to accommodate various types that adhere to an interface?

How can we create a function that can accept multiple types with a common interface? Let's consider the example: interface A {a: number} type B = {b: string;} & A type C = {c: string;} & A function acceptA(a: A) { return a } acceptA({a ...