Create a function that takes in a function as an argument and generates a new function that is identical to the original function, except it has one

I want to establish a function called outerFn that takes another function (referred to as innerFn) as a parameter. The innerFn function should expect an object argument with a mandatory user parameter. The main purpose of outerFn is to return a new function (known as returnFn) that resembles the type of innerFn, but without requiring the user parameter in its argument object (while still needing all other arguments).

This setup allows me to have outerFn return a returnFn that essentially executes the innerFn automatically injecting the user (without the need for manually passing it).

For example:

type User = { user: { id: number, name: string } };
// More code examples here...

In my attempt at implementing outerFn, I encountered an error concerning the parameters passed to innerFn.

// TypeScript code showcasing the issue...

The specific error message related to the assignment between different types and constraints within the function. I am struggling to comprehend why the typings are incorrect in this scenario.

If you can provide any insights or assistance on understanding why the typing mismatch occurs, it would be greatly appreciated.

Answer â„–1

It seems that the error you're encountering is valid from a technical perspective. The compiler is cautious because it cannot guarantee that the argument type of innerFn will accept a broad "User" for its "user" property. An example illustrating the compiler's concern is provided below:

const innerFn = async (arg: {
    user: { id: number, name: "a" | "b" }
}) => ({ a: 1, b: 2 }[arg.user.name]).toFixed(2);

In this case, innerFn demands its argument to have the type

{ user: { id: number, name: "a" | "b" } }
, which is more specific than simply "User." Attempting to call innerFn() with an argument of type User could result in a runtime error if arg.user.name is neither "a" nor "b", leading to a TypeError due to dereferencing undefined.

However, your typings for outerFn() do accept innerFn without any issues:

const returnFn = outerFn(innerFn); // no compiler error

The inferred type Args is

{user: {id: number; name: "a" | "b"}}
, and
Omit<Args, "user"> & { user: { id: number; name: string; }; }
essentially equates to User. However, this alignment does not cater to what innerFn specifically requires. This conflict arises because:

// 'Omit<Args, "user"> & { user: { id: number; name: string; }; }' is assignable to the constraint of 
// type 'Args', but 'Args' could be instantiated with a different subtype of constraint 'ArgsWithUser'.

Consequently, executing returnFn() might lead to a runtime error without any prior warning from the compiler:

returnFn({}).catch(e => console.log(e)) // no compiler error, but:
// đŸ’¥ (intermediate value)[arg.user.name] is undefined 

This situational inconsistency exists. While quite unlikely, you may consider performing an assertion (or what you referred to as a "cast") to swiftly move forward.


If you wish to refactor and circumvent this issue effectively, you can incorporate "User" into a type by supplementing it instead of excluding it:

type InnerFn<A, R> = (args: A & User) => Promise<R>
type ReturnFn<A, R> = (args: A) => Promise<R>

const outerFn = <A, R>(innerFn: InnerFn<A, R>): ReturnFn<A, R> => {
    const user: User['user'] = {
        id: 1,
        name: 'Something',
    };
    return async (argsWithoutUser) => innerFn({ ...argsWithoutUser, user });
};

This solution entails no compilation errors and functions correctly with the examples presented. Its applicability to your specific scenario remains uncertain, but the compiler satisfaction stands nevertheless.

Playground link to code

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 JSX element with type 'Component' does not support any construct or call signatures at this time

I am facing an issue with the following code snippet const pageArea = (Component:ReactNode,title:string) => ({ ...props }) => { return ( <> <div> { Component && (<Component { ...

Angular ngFor not displaying the list

I'm encountering an issue with my HTML page where I'm using NGFor with an array. The error message I receive is as follows: landingpage.component.html:142 ERROR Error: Cannot find a differ supporting object '[object Object]' of type &ap ...

The Azure function encounters an AuthorizationFailure error while attempting to retrieve a non-public file from Azure Blob Storage

Within my Azure function, I am attempting to retrieve a file from Blob Storage labeled myappbackendfiles. The initial code (utils/Azure/blobServiceClient.ts) that initializes the BlobServiceClient: import { BlobServiceClient } from "@azure/storage-bl ...

Fixing the "Cannot find name" error by targeting ES6 in the tsconfig.json file

I recently started learning AngularJS through a tutorial. The code repository for the tutorial can be accessed at this link. However, upon running npm start using the exact code provided in the tutorial, I encountered the following error: Various TS2304 e ...

TypeDI is failing to recognize Services from a nearby external package

I've encountered an issue with my mono repo project that contains two packages built using Lerna: Base and Libs. I'm attempting to utilize TypeDi dependency injection, but the classes marked with the Service() decorator from the Libs package are ...

Converting a specific string format to a Date object in TypeScript

I am in need of a solution to convert strings with the given format into Date objects using TypeScript: var dateTimeString:string = "20231002-123343" I have created my own method as shown below: var dateTime:string[] = dateTimeString.split(" ...

There seems to be a contradiction in my code - I am returning a Promise but TypeScript is throwing an error saying that the

I currently have a function that retrieves a bot's inventory on the Frontend fetchBotInventory() { this.socket.emit('fetch bot inv'); this.socket.on('bot inv', (botInventory) => { return new Promise((resolve, re ...

What is the best strategy for managing a sizable react application using react-query?

Since diving into React with functional components and react-query, I've been facing some confusion on how to properly organize my components. Typically, I design components by having a top-level component handle all data access and pass data down to ...

Can you switch out the double quotation marks for single quotation marks?

I've been struggling to replace every double quote in a string with a single quote. Here's what I have tried: const str = '1998: merger by absorption of Scac-Delmas-Vieljeux by Bolloré Technologies to become \"Bolloré.'; console ...

What could be the reason for the defaultCommandTimeout not functioning as expected in my script

Is there a way to wait for only one particular element in Cypress without having to add wait commands everywhere in the test framework? I've come across the solution of adding defaultCommandTimeout in the cypress.json file, but I don't want it t ...

The JavaScript code is executing before the SPFX Web Part has finished loading on the SharePoint page

I recently set up a Sharepoint Page with a custom masterpage, where I deployed my SPFx Webpart that requires certain javascript files. While the Webpart functions correctly at times, there are instances when it doesn't work due to the javascript bein ...

Adjust the transparency and add animation effects using React JS

When working on a React project, I encountered an issue where a square would appear under a paragraph when hovered over and disappear when no longer hovered. However, the transition was too abrupt for my liking, so I decided to implement a smoother change ...

An issue has arisen with the TypeScript function classes within the React Class, causing a compile error to be thrown

I am currently in the process of transitioning a React object from being a function to a class. This change is necessary in order to save the state and bind specific functions that I intend to pass to child components. Unfortunately, during compilation, I ...

Handling exception type in child_process exec method - NodeJS with Typescript integration

Check out this sample code: const execPromise = util.promisify(exec); try { const { stdout } = await execPromise(cliCommand); } catch (error) { if (error instanceof S3ServiceException) { // error message is not handled correctly console ...

transform json array into a consolidated array by merging identical IDs

I need to transform an array into a different format based on the values of the ID and class properties. Here is the initial array: const json = [{ "ID": 10, "Sum": 860, "class": "K", }, { "ID": 10, "Sum": 760, "class": "one", }, { "ID": ...

Bringing PNGs and SVGs into React - Error TS2307: Module not found

While attempting to import PNGs/SVGs (or any other image format) into my React project, TypeScript presents the following error: TS2307: Cannot find module '../assets/images/homeHeroImage.svg' or its corresponding type declarations. The frontend ...

Encountered an issue with Webpack 5 - A ReferenceError was thrown: require is not recognized

I encountered an error while attempting to access the main page of my app in the browser: Uncaught ReferenceError: require is not defined at Object.events (main.bundle.js:90508:1) at __webpack_require__ (main.bundle.js:91217:33) at fn (main.bundle.js:91451 ...

Is there a way to utilize Angular in identifying whether a given value corresponds with the value of a particular radio button within my application?

I have an array of lists that I need to display in radio buttons. Like this: https://i.stack.imgur.com/cmYgO.png https://i.stack.imgur.com/Zx4bm.png https://i.stack.imgur.com/jBTe3.png My goal is to have a checkbox that matches the values loaded from a ...

Implementing Typescript for React Navigation: Configuring navigationOptions effectively

Within a React Native app utilizing React Navigation, I am working on a screen component where I aim to set the title based on given parameters using the navigationOptions property like so: static navigationOptions = ({navigation}) => ({ title: nav ...

Animating with Angular 2

As I delve into this informative resource, my goal is to incorporate some animations into my applications, but I find myself grappling with understanding how the animations are triggered. HTML Component <div class="navbar navbar-default navbar-fixed-t ...