Deriving the type of a generic parameter from another generic parameter in TypeScript

Apologies for the less-than-descriptive title of this question, but sometimes it's easier to demonstrate with code rather than words. Here's a snippet that's causing issues, and I'm wondering why it's not behaving as expected:

interface Doer<U> {
    doStuff: () => U;
}

class Promiser implements Doer<Promise<string>> {
    doStuff() {
        return Promise.resolve('foo');
    }
}

export interface Type<T> extends Function {
    new (...args: any[]): T;
}

function doYourThing<T extends Doer<U>, U>(doer: Type<T>): U {
    return new doer().doStuff();
}

const result = doYourThing(Promiser);
// the type of "result" is `{}`
// but I'm aiming for it to be `Promise<string>`

You can tinker with the code above here.

I'm not entirely certain if this can be done, but I'm hoping that TypeScript can deduce the return type of doYourThing() based on the argument being of type Doer<U> and said argument actually being of type

Doer<Promise<string>>
.

Is my goal achievable (currently using TypeScript 2.4.2)?

If so, where am I faltering in my approach?

Answer №1

The direct implementation of higher-kinded typing may not be supported easily. However, there is an alternative approach called the "flattened" encoding of HKTs, as described in the concept of "lightweight higher kinded typing" (You can find TypeScript examples here). This method may provide improved inference capabilities.

Fortunately, there is a simpler way to reorganize the code for your specific scenario:

...

function executeAction<T>(action: Type<ActionHandler<T>>): T {
    return new action().performAction();
}

const result = executeAction(Executor);
// The result will be of type `Promise<string>`

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

Is it true that a TypeScript derived class is not allowed to have identical variable names?

Why is it not allowed for TypeScript derived classes to have the same variable name, even if these members are private? Is there another way to achieve this, or am I making a mistake? class ClassTS { private nom: string = "ClassTS"; ...

Navigating back to the login page in your Ionic V2 application can be achieved by utilizing the `this.nav

Running into an issue with navigating back to the login screen using Ionic V2. Started with the V2 tabs template but added a custom login page, setting rootPage = LoginPage; in app.components.ts. When the login promise is successful, I used this.nav.setR ...

Retrieve data from a JSON object within an HTML document

How do I display only the value 100 in the following div? <div> {{uploadProgress | async | json}} </div> The current displayed value is: [ { "filename": "Mailman-Linux.jpg", "progress": 100 } ] Here is my .ts file interface: interface IU ...

Error TS2322: The object with properties "ready: false" and "session: null" cannot be assigned to the type "Readonly<S & withAuthState>"

Here is the interface I'm currently working with: export interface withAuthState { ready: boolean, session: any } Additionally, I have developed the following Higher Order Component (HOC): const withAuth = <P extends withAuthProps, S extends ...

Error Message: The Reference.update operation in Angular Firebase failed due to the presence of undefined value in the 'users.UID.email' property

Having recently started to use the Firebase database, I encountered an issue while trying to update the UID to the Realtime Database during signup. The error message displayed was: Error: Reference.update failed: First argument contains undefined in prop ...

Angular: Nodemailer is encountering an abundance of runtime errors

Within my Angular project, I am attempting to utilize Nodemailer for sending emails. The initial issue arises when I try to import (after running npm i --save) as numerous errors occur when executing ionic serve. It's important to note that right aft ...

Error: module not found in yarn

https://i.sstatic.net/3zEMq.png In my yarn workspace, I have organized folders named public and server. While working with TypeScript in VS Code, I encounter an error message stating: Cannot find module 'x' Interestingly, even though the error ...

Describe the TypeScript type for an object with constant keys

My query resembles the one found in this Typescript interface definition question, but has a slight variation. I am beginning with an object where the keys are constants: const KEYS = { KEY1: 'hello', KEY2: 'world' } as const; How ...

Retrieve a collection within AngularFire that includes a subquery

I have the following function getParticipations( meetingId: string ): Observable<Participation[]> { return this.meetingCollection .doc(meetingId) .collection<ParticipationDto>('participations') .snapshotCh ...

In TypeScript and React, what is the appropriate type to retrieve the ID of a div when clicked?

I am facing an issue in finding the appropriate type for the onClick event that will help me retrieve the id of the clicked div. const getColor = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => { const color = event.target.id; // ...

Using template strings in a Mongoose update query when working with TypeScript

When working with a mongoose update query in typescript, I am trying to incorporate a template string. The specific field I need to update is a Map named messages, which consists of string keys and array values of type Message. interface Message { conte ...

Server-side props become inaccessible on the client side due to middleware usage

I'm attempting to implement a redirect on each page based on a specific condition using Next.js middleware. Strange enough, when the matcher in middleware.ts matches a page, all props retrieved from getServerSideProps for that page end up being undef ...

Tips for implementing a feature in Angular 6 that enables an input box to accept both negative and positive values within the range of 0 to

HTML markup <input type="number" min="0" max="100" required placeholder="Charge" [(ngModel)]="rateInput" name="rateInput" [formControl]="rateControl"> Implementing TypeScript validation this.rateControl = new FormControl("", [Validators.max(100) ...

The attribute specified is not present on the element within the array

I'm attempting to create an array that includes an object with initialized properties and a number. Yet, I encounter this error message: The error states: 'Property 'foo' does not exist on type 'number | IObj'. The proper ...

The name 'XXX' is nowhere to be found

I encountered an error stating "Cannot find name 'Calendar Component'" while attempting to add a route to a component from another module in my app.module.ts file. Below is the content of my app.module.ts file: // Importing Modules // import {B ...

Using TypeScript in Node.js to iterate through an asynchronous forEach loop

I attempted to integrate a database operation within an async forEach loop with the following code snippet: let successCounter = 0; let failureCounter = 0; let myData = [101, 102, 104, 105]; myData.forEach(async data => { let response = awai ...

Here's a unique version: "Utilizing the onChange event of a MaterialUI Select type TextField to invoke a function."

I am currently working on creating a Select type JTextField using the MaterialUI package. I want to make sure that when the onChange event is triggered, it calls a specific function. To achieve this, I have developed a component called Select, which is es ...

Top recommendation for showcasing a numerical figure with precision to two decimal points

Within my function, I am tasked with returning a string that includes a decimal number. If the number is whole, I simply return it as is along with additional strings. However, if it's not whole, I include the number along with the string up to 2 deci ...

What is causing the duplication of leaves when using this DFS implementation?

I created an algorithm to compare if two trees have the same leaves. https://i.sstatic.net/lpO2C.png Both trees display matching leaf numbers in the exact order, resulting in a true outcome. Below is the code that I formulated: function leafSimilar(root ...

What is the best way to deliver a file in Go if the URL does not correspond to any defined pattern?

I am in the process of developing a Single Page Application using Angular 2 and Go. When it comes to routing in Angular, I have encountered an issue. For example, if I visit http://example.com/, Go serves me the index.html file as intended with this code: ...