Wrapper functions that are nested are returning a Promise that resolves to another Promise of type T

I have a function called doesPromiseyThings that wraps a thunk and returns its value inside a Promise. I want to create another wrapper that not only handles the creation of thunks, but also ensures the returned type is a Promise-wrapped version of the original.

The problem arises when passing in a function that already returns a Promise - TypeScript complains that the returned types end up being Promise<Promise<T>>, which is not what I intended.

async function foo(param: number) {
    return param;
}

function doesPromiseyThings<T>(fn: () => T): Promise<T> {
    return Promise.resolve(fn());
}

function wrapper<T,U>(fn: (...args: T[]) => U) {
    return (...args: T[]) => doesPromiseyThings(fn);
}

const wrappedFoo = wrapper(foo);
// (...args: number[]) => Promise<Promise<number>>

const output = wrappedFoo(1);
// Promise<Promise<number>>

I attempted to unwrap the Promise in the wrapper's return value to resolve this issue, but encountered type errors:

function wrapper<T,U>(fn: (...args: T[]) => U): (...args: T[]) => Promise<U extends Promise<infer V> ? V : U> {
    return (...args: T[]) => doesPromiseyThings(fn);
}
/*
Type '(...args: T[]) => Promise<U>' is not assignable to type '(...args: T[]) => Promise<U extends Promise<infer V> ? V : U>'.
  Type 'Promise<U>' is not assignable to type 'Promise<U extends Promise<infer V> ? V : U>'.
    Type 'U' is not assignable to type 'U extends Promise<infer V> ? V : U'.(2322)
*/

Answer №1

I'm not entirely sure of the purpose behind what you're attempting to do here, but I managed to successfully run this code snippet.

It looks like you forgot to pass the arguments while wrapping as well...

You might also consider exploring decorators for handling these types of situations: https://www.typescriptlang.org/docs/handbook/decorators.html

async function foo(param: number) {
    return param
}

function doesPromiseyThings<T>(fn: (args: any) => T, args: any): Promise<T> {
    const promise = new Promise<T>((resolve) => resolve(fn(args)))
    return promise
}

function wrapper<T, U>(fn: (args: T) => U) {
    return (args: T) => doesPromiseyThings(() => fn(args), args)
}

const wrappedFoo = wrapper(foo)

const output = async () => {
    console.log(await wrappedFoo(1))
}

output()

In regards to ..args:

function foo(param: number) {
    return param
}

function doesPromiseyThings<T>({ fn }: { fn: (...args: any[]) => T }): Promise<T> {
    const promise = new Promise<T>((resolve) => resolve(fn()))
    return promise
}

function wrapper<T, U>(fn: (...args: T[]) => U) {
    return (...args: T[]) => doesPromiseyThings({ fn: () => fn(...args) })
}

const wrappedFoo = wrapper(foo)

const output = async () => {
    console.log(await wrappedFoo(1))
}

output()

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

Error in ThreeJS: Unable to execute material.customProgramCacheKey

I encountered an issue TypeError: material.customProgramCacheKey is not a function The error pops up when I invoke the function this.animate(). However, no error occurs when the URL is empty. Where could this error be originating from since I don't ...

The evaluation of mongodb-memory-server is experiencing issues with either failing or timing out

While setting up mongodb-memory-server in my backend for testing purposes, I encountered some issues during test execution that require debugging. The problem arises when running a test that creates a MongoDB document within the service being tested, leadi ...

guide to utilizing npm/yarn with tsx react

I've recently made the switch to using TypeScript with React, but I'm encountering a problem. After installing certain packages from npm or yarn, I'm having trouble using them in my .tsx components. The error message suggests looking for @ty ...

How can I update a value using a specific key in Angular?

So, I have a string value that I need to pass to another function. For instance, if the string is 'eng', I want it to be converted to 'en'. I'm looking for a solution that does not involve using slice or if statements. I attempted ...

Utilizing NgClass Within an Attribute Directive in Angular 2.4.0

Is there a way to utilize NgClass within a custom attribute directive to modify the CSS class of the main elements? For example, if I have this code snippet: @Component({ selector: 'my-app', template: ` <div> <div class=" ...

The attribute 'y' is not found within the data type 'number'

Currently working on a project using Vue.js, Quasar, and TypeScript. However, encountering errors that state the following: Property 'y' does not exist on type 'number | { x: number[]; y: number[]; }'. Property 'y' does not ...

The struggle of implementing useReducer and Context in TypeScript: A type error saga

Currently attempting to implement Auth using useReducer and Context in a React application, but encountering a type error with the following code snippet: <UserDispatchContext.Provider value={dispatch}> The error message reads as follows: Type &apos ...

Utilizing Angular 2 or TypeScript to Retrieve Visitor's Location

I initially began using ServerVariables["HTTP_CF_IPCOUNTRY"] on the backend server, but it's proving to be too slow. I'm looking for an Angular or TypeScript alternative to speed things up. ...

Despite the error message stating that it cannot find module 'angular2/core', the application is still functioning properly

Imagine you have an Angular2 application with a file named app.component.ts that contains some import statements: import {Component} from 'angular2/core'; import {FiltersService} from "./services/filters-service"; import {SearchPipe} from "./ ...

What is the process for creating static pages that can access local data within a NextJS 13 application?

I recently completed a blog tutorial and I must say, it works like a charm. It's able to generate dynamic pages from .md blog posts stored locally, creating a beautiful output. However, I've hit a roadblock while attempting what seems like a sim ...

Tips for accessing an API and setting up data mapping for a data table in nuxt.js

I desperately need assistance. I have been struggling with this issue for a while now, but all my attempts have ended in failure. My objective is to retrieve API data that corresponds to an array containing name, id, and email, and then display this inform ...

Bidirectional data binding in Angular 2 allows for communication between parent components and directives

Update: Experimenting with Angular2 Beta, I am working on incorporating an "editor" component template that includes a directive wrapping the Ace editor. In this scenario, the "editor" component acts as the parent of the Ace wrapper directive, and my goal ...

Locating Items in an Array using Angular 5 and Forming a New Array with the Located Objects

Looking for a way to extract objects from an array that have the type "noActiveServiceDashboard" and "extraAmountDashboard". I want to create a new array with only these two entries in the same format. I've attempted using .find() or .filter() method ...

Verify the dates in various formats

I need to create a function that compares two different models. One model is from the initial state of a form, retrieved from a backend service as a date object. The other model is after conversion in the front end. function findDateDifferences(obj1, ...

The 'target' property is not found on the specified 'string' type

I've encountered an issue while creating a search bar in Typescript. Despite my efforts, the input is not being recognized. It seems that whenever I use the term 'target' in my onChange method, it triggers an error stating: Property &ap ...

Ways to retrieve a URL from the assets folder

I need to establish a baseUrl for my backend requests within the assets folder. For this, I have created a server configuration file named config.json { "backendServer": { "protocol": "http", "host": " ...

How to toggle visibility of multiple div elements in ReactJS

When working in react-js, I encountered a situation where two div elements and two buttons were used. Clicking the first button displayed the first div and hid the second div. Conversely, clicking the second button showed the second div and hid the first d ...

To determine if two constant objects share identical structures in TypeScript, you can compare their properties

There are two theme objects available: const lightMode = { background: "white", text: { primary: "dark", secondary: "darkgrey" }, } as const const darkMode = { background: "black", text: { prim ...

Bring in a function by its name from the ts-nameof package that is not declared in the d.ts export

Recently, I came across a captivating package that caught my interest and I would love to incorporate it into my TypeScript application: https://github.com/dsherret/ts-nameof However, upon attempting to import the nameof function, I realized it was not be ...

After the for loop, I must gain access to all the data from Axios

I have created a basic word combination website and I am facing an issue in getting all possible words in one string. Here is the code snippet that I have written: const fs=require('fs'); const axios=require('axios') function test(want) ...