Is there a method to increase the level of generality of an object containing generic functions?

Here is a unique question that delves into the nuances of type manipulation in TypeScript. Rather than focusing on obtaining return values of generic functions, this query explores transforming a specific type Have into another type Want<T>.

Imagine having an object with properties that are all functions, some of which are generic functions with a single parameter. For example:

type Have = {
  foo: <T>(dep: {dependency: (a:T, b:T) => T}) => (a:T) => T
  bar: <T>() => (a: T) => string
}

The goal here is to create a new generic type, Want<T>, where each property corresponds to the type of the function in the original object but instantiated at the given parameter. In this case, the desired outcome would be:

type Want<T> = {
  foo: (dep: {dependency: (a:T, b:T) => T}) => (a:T) => T
  bar: () => (a: T) => string
}

So, the question remains: Is there a way to transform the type Have into Want<T>? This could involve purely type-level manipulation or potentially utilizing an object of type Have as well.

Answer №1

If you're using TypeScript 5.2, the closest approach would be to drop down to the value level and utilize an instantiation expression for each member. Unfortunately, incorporating instantiation expressions purely at the type level is not feasible, as highlighted in this comment on microsoft/TypeScript#47607, where instantiation expressions are implemented. This limitation means it's impossible to achieve programmatically over a range of types like the members of an object type. Even attempting to do so through a mapped type will not yield successful results (refer to microsoft/TypeScript#52035)

Therefore, the following represents the optimal solution:

type Have = {
  foo: <T>(dep: { dependency: (a: T, b: T) => T }) => (a: T) => T;
  bar: <T>() => (a: T) => string;
}

declare const have: Have;
const wantMaker = <T,>() => ({ foo: have.foo<T>, bar: have.bar<T> });
type Want<T> = ReturnType<typeof wantMaker<T>>;

/* type Want<T> = {
    foo: (dep: {
        dependency: (a: T, b: T) => T;
    }) => (a: T) => T;
    bar: () => (a: T) => string;
} */

This method necessitates crafting a distinct expression for each member of Have. If this approach doesn't align with your requirements, achieving what you desire is presently unattainable.

Link to code on Playground

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

Limitations of MaterialUI Slider

Looking for a solution to distribute 350 points across 8 sliders, each with a range of 0-100 and 5 marks at 0, 25, 50, 75, and 100. With each step consuming or returning 25 points, the challenge lies in allowing users to adjust the points allocation withou ...

Angular - postpone function execution until Subject has completed its operation

In my code, there is a function that stops a running process using a specified processId. Before this function is executed, there is a single if statement that checks if a valid processId exists, and if so, it calls the cancel() function. if (this.process ...

Tips for uploading images, like photos, to an iOS application using Appium

I am a beginner in the world of appium automation. Currently, I am attempting to automate an iOS native app using the following stack: appium-webdriverio-javascript-jasmine. Here is some information about my environment: Appium Desktop APP version (or ...

What is causing the failure of the state to be inherited by the child component in this scenario (TypeScript/React/SPFX)?

For this scenario, I have a Parent class component called Dibf and a Child class component named Header. While I can successfully pass props from the Parent to the child, I am encountering difficulties when trying to pass state down by implementing the fo ...

What is the best way to access the data stored within a Promise object in a React application?

Below is the snippet of my code that handles parsing application data: async function parseApplication(data: Application) { const fieldGroupValues = {}; for (const group of Object.keys(data.mappedFieldGroupValues)) { const groupValue = data.mappedF ...

The program encountered a problem stating that the 'getItem' property is not found within the 'string' type

I am utilizing Firebase to register links on a website. I'm attempting to pass the uuid in order to create a sub collection, but have been unsuccessful. Any idea what might be causing this issue? constructor(private af: AngularFirestore) {} async add ...

Unable to find custom components when using react-router

My goal is to improve the organization of my Routes in React and separate concerns. I am currently utilizing react-router-dom version 5. Within my Application Routes component, I have structured it with 3 children components: AuthenticatedRoutes PublicRo ...

Adding dynamic values to nested form groups in Angular Form Array

After following a tutorial on creating a reactive form in an Angular application, I managed to implement it successfully. However, I encountered an issue when trying to add an additional control called "setNumber" to the form array. I want this control to ...

Issue encountered while attempting to package Azure project in Visual Studio 2015 Update1 due to difficulty copying Typescript files

Since upgrading to VS 2015 Update 1 (that includes Typescript 1.7) and Azure SDK 2.8, packaging my Azure application for deployment has become a challenge due to an error in the file path where the packager is attempting to copy the js output file: Erro ...

Exploring the power of EJS with conditional logic

Can someone help me figure out why EJS is not evaluating to the else branch in my code? I'm using EJS version 3.1.5 with express version 4.17.1 and typescript. ReferenceError: /home/pauld/tscript/dist/views/index.ejs:12 10| </head> 11| & ...

Using data analysis to customize the appearance of boundaries across various map styles - Google Maps Javascript API V3

Utilizing data-driven styling for boundaries in Google Maps Javascript API V3 is a fantastic feature that appears to be compatible with all map types such as terrain, satellite, and hybrid. Nevertheless, I have encountered difficulties in making it visible ...

React Routing: Unleashing the Power of Multi-Level Routing

In my quest to create a route with multiple levels (<Route path="/hello/world" element={<a>hello world</a>} />), I encountered a few issues. Here are the versions I am using: react: 18.1 react-router-dom: 6.3.0 Success with O ...

How can I ensure that TypeORM, Type GraphQL, Apollo Server, and Azure Functions work together seamlessly?

I have an Azure Function written in TypeScript that utilizes various technologies such as TypeORM, Apollo Server, and TypeGraphQL. The function involves creating resolvers for projects and tasks and establishing a database connection. import { createConne ...

I'm experiencing an issue with redirect in Nextjs that's causing an error message to appear. The error reads: "SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

I'm currently diving into the world of NextJS and working on creating a simple recipe application. Utilizing the new App Router has been smooth sailing for the most part, except for one hiccup with the login function. After successfully logging in (us ...

Stop the ability to "submit" inline edits in AG-Grid

Currently, I am attempting to implement an inline-editable table using Ag-Grid (v 17.0). However, I have encountered an issue where once I finish editing a row and press enter, the changes are immediately saved. Ideally, I would like the user to remain in ...

The assigned type 'string' for Apache ECharts does not match the expected type 'pictorialBar'

This demonstration is functional. Nevertheless, the options utilize any and my goal is to convert them to the EChartOption type. This is my current progress and the demonstration compiles successfully with this setup (With type: 'bar' commented ...

The solution to automatically delete orphaned rows in TypeORM

Having a one-to-many relationship in TypeORM, I am interested in deleting rows from the many side of the connection rather than just unlinking them and leaving orphaned entries. Can anyone suggest a way to achieve this since the proposed feature for it w ...

Issue with accessing form in Angular 6 Reactive forms for custom validator functionality

I am facing an issue with creating a password validation for reactive forms in Angular. Every time I try to verify the password, I get a “Cannot read property 'get' of undefined” error in the console. I have tried different methods to access ...

Angular is experiencing difficulty locating the routing path for the auxiliary `router-outlet`

Exploring the intricacies of routing in Angular to gain a deeper understanding of the concept. Encountering an issue where I am receiving an exception NG04002: Cannot match any routes. URL Segment: 'about' when attempting to click on the About li ...

Angular - Utilizing NgRx selector for efficient data update notifications

Is there a method to create a "data updated" indicator when I am not interested in the actual updated data itself? Consider a scenario with a reducer: const initialState: SomeReducer = { dataInQuestion: Array<SomeDto>, ... } Following an action ...