Monitor a universal function category

Trying to implement a TypeScript function that takes a single-argument function and returns a modified version of it with the argument wrapped in an object. However, struggling to keep track of the original function's generics:

    // ts v4.5.5

    type FnType<Arg, Ret> = (arg: Arg) => Ret
    
    type Wrapped<VFn extends FnType<any, any>> = (wrap: {
      _: VFn extends FnType<infer A, any> ? A : never
    }) => VFn extends FnType<any, infer B> ? B : never
    
    // Created a function that takes a `FnT extends FnType` and produces Wrapped<FnT>
    type Wrapper = <FnT extends FnType<any, any>>(v: FnT) => Wrapped<FnT>
    declare const wrapper: Wrapper
    
    // The resulting `wrapped` function loses track of generic type T
    const wrapped1 = wrapper(<T>(t: T) => ({ t })) // const wrapped1: Wrapped<(<T>(t: T) => { t: T; })>
    const ret1 = wrapped1({ _: { a: 1 } }) // const ret1: { t: unknown; }
    
    
    type MyFnType = <T>(t: T) => { t: T }
    const myFnType:MyFnType = <T>(t: T) => ({ t })
    
    // Even explicitly defining and passing FnType as generic and argument !
    
    const wrapped2 = wrapper<MyFnType>(<T>(t: T) => ({ t })) // const wrapped2: Wrapped<MyFnType>
    const ret2 = wrapped2({ _: { a: 1 } }) // const ret2: { t: unknown; }
    
    const wrapped3 = wrapper<MyFnType>(myFnType) // const wrapped3: Wrapped<MyFnType>
    const ret3 = wrapped2({ _: { a: 1 } }) // const ret3: { t: unknown; }

Check code on TS sandbox

Answer №1

When utilizing a conditional type to extract parameters and return types in TypeScript, generics are not preserved through functions.

To maintain generics, you can use the args and return type as type parameters when defining the function:

type Wrapper = <A, R>(v: (a: A) => R) => (a: { _: A }) => R
declare const wrapper: Wrapper


const wrapped1 = wrapper(<T>(t: T) => ({ t }))
const ret1 = wrapped1({ _: { a: 1 } }) // const ret1: { t: { a: number }; }

Visit Playground Link for more details

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

Angular: Implementing conditional HTTP requests within a loop

Currently, I am facing a challenge where I need to loop through an array of objects, check a specific property of each object, and if it meets certain criteria, make an HTTP request to fetch additional data for that object. The code snippet below represen ...

Is there a way to change a .pptx document into a base64 string?

Currently, I am working on a project that involves creating an addin for Office. The challenge I am facing is opening other pptx files from within the addin. After some research, I discovered that I need to use base64 for the PowerPoint.createPresentation( ...

AngularTS - Using $apply stops the controller from initializing

Every time I launch the application, the angular {{ }} tags remain visible. Removing $scope.$apply eliminates the braces and displays the correct value. I am utilizing Angular with Typescript. Controller: module Application.Controllers { export class Te ...

Setting up Typescript with React 17 and Tailwind CSS version 2.0

I'm struggling to set up TailwindCSS 2.0 with the create-react-app --template typescript configuration and encountering errors. Even after following the instructions on the official TailwindCSS website for React at https://tailwindcss.com/docs/guides/ ...

Combine Typescript files from a dependent module to aid in debugging within a Next.js application

Trying to debug a project written in Typescript using Next.js, but facing issues with bundling TS files from a local dependent common library. Only JS files are included, which is not sufficient for debugging. The goal is to bundle all TS files from the w ...

Display a dynamic array within an Angular2 view

I have a dynamic array that I need to display in the view of a component whenever items are added or removed from it. The array is displayed using the ngOnInit() method in my App Component (ts): import { Component, OnInit } from '@angular/core' ...

What is the correct way to specify the type in my functional component?

I was trying to define the type in my component in a different way, I know it can be done using classes but is there a way to achieve this with functional components without exporting the interface? Despite my extensive research, I couldn't find any r ...

Unusual Type Inference in Typescript {} when Evaluating Null or Undefined

Upon upgrading from typescript 4.9.3 to 5.0.2, we encountered an error when asserting types. Can someone explain why the function "wontWorking" is not functioning correctly? I expected this function to infer v as Record<string, any>, but instead it ...

Utilize TypeScript enum keys to generate a new enum efficiently

I am in need of two Typescript enums as shown below: export enum OrientationAsNumber { PORTRAIT, SQUARE, LANDSCAPE } export enum OrientationAsString { PORTRAIT = 'portrait', SQUARE = 'square', LANDSCAPE = 'landscape&ap ...

What is the process for defining a type that retrieves all functions from a TypeScript class?

Imagine having a class called Foo class Foo { bar(){ // do something } baz() { // do something } } How can you define a type ExtractMethods that takes a class and returns an interface or type containing the class methods? For example: t ...

The NestJS Backend is always being asked by Grafana to access the /api/live/ws endpoint

After successfully setting up Grafana and Grafana Loki with my NestJS Backend, everything seemed to be working fine. However, I started getting a 404 error from my NestJS because Grafana was requesting the /api/live/ws route. Is there a way to disable thi ...

Exploring Next.js 13: Enhancing Security with HTTP Cookie Authentication

I'm currently working on a web app using Next.js version 13.4.7. I am setting up authentication with JWT tokens from the backend (Laravel) and attempting to store them in http-only cookies. Within a file named cookie.ts, which contains helper functio ...

In Visual Studio, the .js.map files and .js files seem to be mysteriously hidden, leaving only the TypeScript .ts files visible

In the past, I utilized Visual Studio Code for Angular 2 development and had the ability to hide .js and .js.map files from the IDE. Now, I am working on a project using VS 2017 Professional with Typescript, Jasmine, Karma, and Angular 4. Task Runner, etc. ...

How to format a Date object as yyyy-MM-dd when serializing to JSON in Angular?

I have a situation where I need to display an object's 'birthDate' property in the format DD/MM/YYYY on screen. The data is stored in the database as YYYY-MM-DD, which is a string type. I am currently using bootstrap bsDatePicker for this ta ...

Creating a mock instance of a class and a function within that class using Jest

I am currently testing a class called ToTest.ts, which creates an instance of another class named Irrelevant.ts and calls a method on it called doSomething. // ToTest.ts const irrelevant = new Irrelevant(); export default class ToTest { // ... some impl ...

Issue with interface result: does not match type

Hey there! I've been working on creating an interface in TypeScript to achieve the desired return as shown below: { "field": "departament_name", "errors": [ "constraint": "O nome do departam ...

I am seeking advice on how to create an extension for a generic class in TypeScript specifically as a getter

Recently, I discovered how to create extensions in TypeScript: interface Array<T> { lastIndex(): number } Array.prototype.lastIndex = function (): number { return this.length - 1 } Now, I want to figure out how to make a getter from it. For exam ...

Ensuring Koa ctx.query is valid prior to invoking the handler function

I'm currently working on a basic route that looks like this: router.get('/twitter/tweets', async (ctx) => { const { limit, page, search } = ctx.query ctx.body = { tweets: await twitter.all(limit, page, search), } }) The issue I ...

Leveraging Typescript in Firebase Cloud Functions to effectively work with intricate interfaces

When querying a collection on the app side, I am able to automatically cast the result as an interface using Positions constructor that takes in interface IPosition. However, attempting to do the same on the cloud functions side prevents the functions fro ...

What could be the reason for the variable's type being undefined in typescript?

After declaring the data type of a variable in TypeScript and checking its type, it may show as undefined if not initialized. For example: var a:number; console.log(a); However, if you initialize the variable with some data, then the type will be display ...