Is it possible to utilize ReturnType and Parameters in a generic function declaration on TypeScript?

While attempting to create a generic wrapper function, I initially thought the following code would suffice, but unfortunately, it is not functioning as expected:

function wrapFunctionWithLogging<T extends Function>(f: (...args: Parameters<T>) => ReturnType<T>): ReturnType<T>  {
      return function (...args: Parameters<T>) {
        console.log('before ');
        try {
          return f(...args);
        } catch (error) {
          console.error(error);
          throw error;
        } finally {
          console.log('done');
        }
      };
    }

Subsequently, I tried an alternative version using two types:

wrapFunctionWithLogging<TArgs extends any[], TReturn> 

This alternative version seems to be working fine, leaving me inquisitive as to why the initial version is not functioning properly.

Answer №1

Utilize (...args: any[]) => any to define any function in general. Your wrapper function should accept a function with this specific signature and return a function with the same signature, making them both essentially T. It is also crucial to confirm that the return type is indeed T.

function wrapFunctionWithLogging<T extends (...args: any[]) => any>(fn: T): T {
    return function (...args: any[]) {
	  console.log("before execution");
        try {
            return fn(...args);
        } catch (error) {
            console.error(error);
            throw error;
        } finally {
            console.log("execution complete");
        }
    } as T;
}

Interactive Playground

Answer №2

expanding upon the concept of enhancing a function with arguments appears to be effective, even without type assertion:)

function wrapFunctionWithLogging<T extends (...args: any[]) => any>(f: T): (...args: Parameters<T>) => ReturnType<T> {
  return function (...args: Parameters<T>): ReturnType<T> {
    console.log('before ');
    try {
      return f(...args);
    } catch (error) {
      console.error(error);
      throw error;
    } finally {
      console.log('done');
    }
  };
}

TS Fiddle here

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

Define a new type in Typescript that is equal to another type, but with the added flexibility of having optional

I have 2 categories: category Main = { x: boolean; y: number; z: string } category MainOptions = { x?: boolean; y?: number; z?: string; } In this scenario, MainOptions is designed to include some, none, or all of the attributes that belong to ...

The error message "Value property is not found on the FilterMetadata type in the PrimeNG table" indicates that there is an issue with accessing the 'value'

While transitioning a module from Primeng 7 to Primeng 11 in conjunction with Angular 11, everything seems to be running smoothly on ng serve with all functionalities working as expected. However, upon building the project, I encounter an unexpected error. ...

Mastering Inter-Composable Communication in Vue 3: A Guide

Composables in Vue documentation demonstrate how small composition functions can be used for organizing code by composing the app. Discover More About Extracting Composables for Code Organization "Extracted composables act as component-scoped servi ...

Replace Formik with useFormik to streamline your code

I have implemented Formik/Yup for validation on a page that triggers a GraphQL mutation. The code is functioning as expected: export default function RemoveUserPage() { const [isSubmitted, setIsSubmitted] = useState(false); const [isRemoved ,setIsRemo ...

I encounter an issue when trying to declare an enum in TypeScript

At line 26 in my typescript file, the code snippet below shows an enum definition: export enum ItemType { Case = 'Case', Study = 'Study', Project = 'Project', Item = 'Item', } I am currently using Visual Stu ...

Issue with Redis cache time-to-live not adhering to set expiration

I have encountered an issue while using IoRedis and DragonflyDB to implement rate limiting in my web application. Despite setting a TTL of 5 seconds for the keys in the Redis DB, sometimes they do not expire as expected. I am struggling to understand why t ...

A specialized solution designed to avoid loops in references

Is there a method to create a general solution that can prevent circular variables in JavaScript? This solution should be effective for any level of depth or type of circular reference, not limited to the variable itself... So far I've come up with t ...

The type 'Promise<UserCredential>' cannot be assigned to

import React, {createContext, useContext, useEffect, useState, ReactNode} from "react"; import { auth } from '../utils/init-firebase'; import { createUserWithEmailAndPassword } from "firebase/auth" type ButtonProps = { ch ...

The expansion feature of PrimeNG Turbotable

I'm currently facing an issue with the Primeng Turbotable where I am unable to expand all rows by default. You can find a code example of my problem at this link. I have already tried implementing the solution provided in this example, but unfortuna ...

Managing data with Angular 2: Setting and retrieving values

In my current project, I am working on developing a service that can parse data to different components based on various routes. When I call this service within the same component, everything works as expected and I get the desired results. However, when ...

What causes the constant reappearance of props as a parameter in my Home function?

I'm currently in the process of developing an app, and I keep encountering an error related to "props" in my index.tsx file 'props' is declared but its value is never read.ts(6133) Parameter 'props' implicitly has an 'any&apos ...

combine two separate typescript declaration files into a single package

Can anyone help me figure out how to merge two typescript definition packages, @types/package-a and @types/package-b, into one definition package? package-a.d.ts [export package-a {...}] package-b.d.ts [exports package-b {...}] package-mine.d.ts [ export ...

Check out the attributes of a class

I have a TypeScript class that is defined like this: export class MyModel { ID: number; TYPE_ID: number; RECOMMENDED_HOURS: number; UNASSIGNED_HOURS: number; } In a different .ts file, I instantiate this class within a component: export class My ...

Assigning namespaces to a property of classes in typescript: A step-by-step guide

As I work on adding a declaration file to a TypeScript package, I encounter some syntax that looks like this: const Sequelize = require('Sequelize'); //... class Application { Sequelize = Sequelize; } To address this, I created a file named ...

Positioning a Box tag at the bottom using MUI 5

My goal is to position a Box tag at the bottom of the page. Current Behavior: https://i.stack.imgur.com/ZupNo.png I am looking to place a TextField and send button at the bottom of the page on both browser and mobile. I want user messages to be above th ...

Error encountered when dispatching action in ngOnInit: ExpressionChangedAfterItHasBeenCheckedError

I have set up my AppComponent to subscribe to the ngrx store in its constructor: export class AppComponent { submenuItems: Observable<Array<INavigationBarItem>>; constructor(private store: Store<AppState>) { this.submenu ...

Utilizing Angular 2 for Element Selection and Event Handling

function onLoaded() { var firstColumnBody = document.querySelector(".fix-column > .tbody"), restColumnsBody = document.querySelector(".rest-columns > .tbody"), restColumnsHead = document.querySelector(".rest-columns > .thead"); res ...

Choose does not showcase the updated value

My form contains a form control for currency selection Each currency object has the properties {id: string; symbol: string}; Upon initialization, the currency select component loops through an array of currencies; After meeting a specific condition, I need ...

I am unable to utilize NavLink unless it is within the confines of the <Router> component

I am currently developing a React application using react-router-dom. To enhance the user experience with smooth transitions, I integrated framer-motion for page animations. However, I encountered an issue where my navbar was being animated and recreated e ...

No pathways can be established within Core UI Angular

I've been attempting to use the router link attribute to redirect to a new page, but instead of landing on the expected page, I keep getting redirected to the dashboard. Below is an overview of how my project's structure looks: [![enter image de ...