简体   繁体   中英

TypeScript declaration file for function with variable number/type of arguments

headjs does some very crazy JavaScript type things to its API. For instance it takes an arbitrary number of strings (not a string array) for a function. Sometimes it ends that same function call, you can optionally end it with a function, for example.

head.js("scripturl1", "scripturl2",...,callback);

You can also (just as easily) do the following

head.js({scriptlabel:"scripturl1"},{scriptlabel2:"scripturl2"},...., callback);

My question is how the HECK do we describe that in a declaration file? I am all ears here as my current pass seems completely wrong.

The TS language spec refers to variable number/spread parameters as "Rest Parameters". An example interface with a function signature that accepts rest params:

interface IExample {
    fn : (...args : any[]) => any;
}

var x : IExample = {
    fn: function(...args : any[]) {
        for (var i = 0, arg; arg = args[i]; i++) {
            console.log(arg);
        }
    }
}

x.fn(1);
x.fn(1, 2);
x.fn("cat", "dog", "mouse");

Unfortunately, there are some limitations. The "Rest Parameter" has to be the last one in a function's signature -- so you won't be able to capture the type of the callback parameter since it is after the repeating parameter.

If it wasn't, you would have been able to do something like this:

var fn = function(cb: Function, ...args : string[]) {
    ...
}

您可以执行以下操作:

type Action<T extends any[]> = (...args: T) => void

The declaration is simply:

function foo () { //...

The function arguments part of a function declaration in Javascript is just advisory. When calling a function Javascript allows you to call with less than the declared number of arguments (arguments not passed in defaults to undefined ) or with more than the declared number of arguments.

When a function is called, an arguments object is created. The arguments object is a bit like an array (though it is not a proper Array object) that holds each passed in argument.

So, for example, to handle infinite arguments you can simply do:

function foo () {
  for (var n=0; n<arguments.length; n++) {
    alert(arguments[n]);
  }
}

So now you can call foo like:

foo(1,2,3);
foo(1,2,3,4,5,6,7,8);

Beyond that, it is simply a matter of using typeof , itstanceof etc. to detect what type of argument is passed in and process them accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM