'Any way to remove repetition of function parameters? Function parameters as type/alias?

Consider the following example:

class A
{
    register() {
        // Other code
        
        chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => this.onResponse1(msg, sender, sendResponse));
        chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => this.onResponse2(msg, sender, sendResponse));
    }

    onResponse1(msg: any, sender: chrome.runtime.MessageSender, sendResponse?: (response: any) => void) {
        // Process
    }

    onResponse2(msg: any, sender: chrome.runtime.MessageSender, sendResponse?: (response: any) => void) {
        // Process
    }
}

Playground

There are workarounds I will list below that shorten and remove a few repetitions but right now I have to repeat the function signature every time a handler function is declared (msg: any, sender: chrome.runtime.MessageSender, sendResponse: (response: any) => void). I can declare a Function type but I am not aware of anyway to declare a class function using such type without having to repeat the signature.

What is a good way to remove/generalize repeated function signature?


These are my attempts to shorten the above code:

  • Use type alias for long type names:

    type ChrSender = chrome.runtime.MessageSender;
    type SendRes = (response: any) => void;
    
    class A
    {
        onResponse1(msg: any, sender: ChrSender, sendResponse?: SendRes) {
            // Process
        }
    
        onResponse2(msg: any, sender: ChrSender, sendResponse?: SendRes) {
            // Process
        }
    }
    
  • Prevent repetition on the addListener by using destructuring:

        register() {
            // Other code
            chrome.runtime.onMessage.addListener((...params) => this.onResponse1(...params));
            chrome.runtime.onMessage.addListener((...params) => this.onResponse2(...params));
        }
    
  • Use tuple type, however this does change the function signature and output code and IMO, worsen the performance (though usually not a huge issue for applications of this type). I wonder if something better can be achieved:

    type ChrSender = chrome.runtime.MessageSender;
    type SendRes = (response: any) => void;
    type MsgCallback = [message: any, sender: ChrSender, sendResponse?: SendRes];
    
    class A
    {
        register() {
            // Other code
            chrome.runtime.onMessage.addListener((...params) => this.onResponse1(params));
            chrome.runtime.onMessage.addListener((...params) => this.onResponse2(params));
        }
    
        onResponse1(params: MsgCallback) {
            const [msg, sender, sendRes] = params;
            // Process
        }
    
        onResponse2(params: MsgCallback) {
            const [msg, sender, sendRes] = params;
            // Process
        }
    }
    


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source