Converting an array of type T to an array of its return type T through typing

I'm having trouble typing a callback function in TypeScript to map a parameter result. The following function is causing me some difficulty:

type CustomRouteType<TParam = any> = <T>(value?: T) => TParam;
const createRoute = <TTypes extends CustomRouteType[]>
    (dictionary: RouteDictionary<TTypes>,
    callback: (...params: TTypes) => void) => {

    // Logic Here
}
createRoute(
    route`/api/someEndpoint/${Number}/${String}/test`, 
    (p1, p2) => {

});

The route function converts the string literal into a custom dictionary that reveals the parameters in the route, making it impossible to determine the type returned by the route function ahead of time. In this example, the function returns a RouteDictionary<[NumberConstructor, StringConstructor]>, and therefore, the parameters p1 and p2 in the callback are instances of those constructors. I want to convert these parameters to match the ReturnValue types of those constructors.

In Typescript, there is only ReturnValue available and not ReturnValues. How can I successfully map these types so that the parameters of the callback function automatically infer the desired return types?

For further clarification:

class RouteString { 
    constructor(public routeString: string) { } 
}
class RouteParameter<T = any> { 
    constructor(public routeString: CustomRouteType<T>) { } 
}

type RouteDictionary<TTypes extends CustomRouteType[]> = {
    routeParts: (RouteString | RouteParameter)[]
    types: TTypes
}

const route = <TParams extends any[], TTypes extends CustomRouteType<any>[]>
    (template: TemplateStringsArray, ...keys: TTypes): RouteDictionary<TTypes> => {

    let routeParts: (RouteString | RouteParameter)[] = [];
    const stringParts = template.raw || [];

    for (let partIndex = 0; partIndex < stringParts.length; partIndex++) {
        const part = stringParts[partIndex];
        const stringChunks = part.split('/').filter(chunkPart => chunkPart !== String())

        routeParts = [... routeParts, ...stringChunks.map(chunk => new RouteString(chunk))]

        if (keys.length === 0) continue
        if (keys.length < partIndex) continue

        const routeParam = keys[partIndex]
        if (!routeParam) continue

        routeParts = [...routeParts, new RouteParameter(routeParam)]
    }

    return {
        routeParts,
        types: keys
    };
}

Answer №1

To transform the tuple of functions into a tuple of return values, you can utilize a mapped type:

type ReturnValuesOf<T extends Array<(...args: any[]) => any>> = {
  [Index in keyof T]: T[Index] extends (...args: any[]) => any ? ReturnType<T[Index]> : never
}
type RouteDictionary<T> = T 
type CustomRouteType<TParam = any> = <U>(value?: U) => TParam;
const createRoute = <TTypes extends CustomRouteType[]>
    (dictionary: RouteDictionary<TTypes>,
    callback: (...parameters: ReturnValuesOf<TTypes>) => void) => {

    // Add your logic here
}

function defineRoute<T extends any[]>(s: TemplateStringsArray, ...values: T): T {
  return values;
}
createRoute(    
    defineRoute`/api/someEndpoint/${Number}/${String}/test`, 
    (param1, param2) => { // param1 is a number, and param2 is a 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

Can we set a specific length for an array passed in as a prop?

Can we use Typescript to specify the exact length of an array coming from props? Consider the following array of objects: const sampleArray = [ { key: '1', label: 'Label 1', value: 9 }, { key: '2', label: 'Label 2&ap ...

Navigating the enum data model alongside other data model types in Typescript: Tips and Tricks

In my different data models, I have utilized enum types. Is it possible to compare the __typename in this scenario? enum ActivtiyCardType { Dance, ReferralTransaction, } type ActivityCardData = { __typename:ActivtiyCardType, i ...

Issue encountered with JavaScript function within TypeScript file connected to HTML code

I am currently working on a simple SharePoint web part and encountering an issue with using a function from another module file in my main file. Snippet from the JSFunctions.module.js file (where I define my function): function getApi(){ [my code]... }; ...

Issue with action creator documentation not displaying comments

We are exploring the possibility of integrating redux-toolkit into our application, but I am facing an issue with displaying the documentation comments for our action creators. Here is our old code snippet: const ADD_NAME = 'ADD_NAME'; /** * Se ...

The issue of transforming a circular structure into JSON arises while using tRPC

While using the t3-stack (Next, tRPC, Prisma, Next-auth, Typescript) tRPC encountered an error on undefined: TRPCError: Converting circular structure to JSON --> starting at object with constructor 'RequestHandler' | property &apos ...

Tips for changing a created Word file with Docxtemplater into a PDF format

Hey there! I am currently in the process of building a website with Angular.js and have successfully managed to generate a word document from user input. Everything was working fine until I encountered an issue. I now need to provide a way for users to pr ...

Setting a default time on a p-calendar: A step-by-step guide

I am currently using the following p-calendar component in my webpage: <p-calendar [style]="{'width':'100%'}" [inputStyle]="{'width':'100%'}" dateFormat="dd-mm-yy" [fo ...

Experiencing difficulties with the mat-card component in my Angular project

My goal is to implement a login page within my Angular application. Here's the code I've written: <mat-card class="login"> <mat-card-content> <div class="example-small-box mat-elevation-z4"> ...

What steps can I take to troubleshoot and repair my accordion feature within an Angular project?

As a newcomer to Angular, I recently attempted to create an accordion component but encountered unexpected behavior. Here is the HTML code for my attempt: <div class="faq-item-container"> <h1 class="mt-1 mb-5"><strong>Frequently A ...

Is there a way to combine compiling TypeScript and running the resulting .js file into one build command in Sublime Text 3?

I have successfully installed the TypeScript plugin on Sublime Text 3. Once installed, a build system is added to the menu for easy access. https://i.stack.imgur.com/m21bT.png You can simply press "Command + B" to build a .ts file. My goal is to compile ...

What is the process for publishing TypeScript interface definitions via npm?

I've been grappling with this problem for the past few days, scouring the internet and reading extensively, but I haven't come across any examples that match my specific scenario. My goal is to publish a library using npm that includes its own ty ...

Checking if a string in Typescript contains vowels using Regex

Is there anyone who can assist me with creating a regex to check if a string contains vowels? EX : Hi Team // True H // False I have tried using the following regex but it's not giving me the desired outcome. [aeiou] ...

Encountering challenges with Object-Oriented Programming combined with Typescript: Are you experiencing a

Currently, I'm in the process of building a comprehensive authentication application using the MERN stack entirely in TypeScript. However, I am encountering some issues (specifically type errors) with my userController file. Here is my routes file: i ...

Broadening Cypress.config by incorporating custom attributes using Typescript

I'm attempting to customize my Cypress configuration by including a new property using the following method: Cypress.Commands.overwrite('getUser', (originalFn: any) => { const overwriteOptions = { accountPath: `accounts/${opti ...

Why is it that Chart.js fails to render in a child component, yet works perfectly in the parent component?

I attempted to create a chart in a parent component using a child component but encountered some difficulties. Here is my code: Parent component: @Component({ selector: 'app-tickets', template: '<canvas id="newChart">< ...

Tips for ensuring proper dependency regulations in javascript/typescript/webpack

In essence, I am in search of a method to limit dependencies, similar to how one would manage different projects (libraries) in Java or C#. Think of it as friend or internal access modifiers. I'm considering various approaches to accomplish this (suc ...

What methods can I use to eliminate redundant information from a dropdown selection?

<option *ngFor="let type of UserTypes; let i = index" [ngValue]="type.id"> <span>{{type.name}}</span> </option> I am looking for a solution to eliminate repeated data in the dropdown options. ...

Typescript not being transpiled by Webpack

As I set out to create a basic website, I opted to utilize webpack for packaging. TypeScript and SASS were my choice of tools due to their familiarity from daily use. Following the documentation at https://webpack.js.org, I encountered issues with loaders ...

Utilizing Typescript for manipulation of Javascript objects

Currently, I am working on a project using Node.js. Within one of my JavaScript files, I have the following object: function Person { this.name = 'Peter', this.lastname = 'Cesar', this.age = 23 } I am trying to create an instanc ...

What programming language is the best choice for Angular 2 development?

As someone who is new to Angular 2, I've discovered that developers have the option to use TypeScript, ES6, and ES5 for their development needs. I understand that TypeScript is considered the superset of ES6 and ES5. Given the stark differences in sy ...