Bruno Grieder
Bruno Grieder

Reputation: 29814

Definition and implementation for function accepting an array or variable/rest parameters

A function fn has the overloaded signatures:

public fn(...arg:T[]);
public fn(args:T[]);

so that fn can be called using either fn([T1,T2,T3]) or fn(T1,T2,T3)

What is the "best" definition for that function ? (one that encourages my IDE to enforce the typing and that avoids arguments type testing boilerplate as much as possible)

Obviously, I can implement a fn(args) definition and test typeof arguments[0] in the implementation, but it would seem that since both have a parameter of type T[], something less generic can be done.

(typescript 1.0.1)

EDIT

What I would like to avoid is something like this:

public fn(...arg:string[]);
public fn(args:string[]);
public fn() {
    if (typeof arguments[0] === 'string') {
          //fn(...args:string[]) called
    }
    else {

    }
}

This seriously weakens the purpose of declaring

public fn(...arg:string[]);
public fn(args:string[]);

in the first place and this does not benefit from the fact that the parameter type isstring[] in both cases

(declaring the definition with the implementation fn() as private would have been an improvement but all definitions must have the same visibility)

Upvotes: 0

Views: 97

Answers (1)

Fenton
Fenton

Reputation: 250882

My recommendation is to implement the rest parameter version. If you really need to call that version with an array, you still can, using apply:

class Example {
    test(...strArray: string[]) {
        alert(strArray.length.toString());
    }
}

var example = new Example();

example.test('a', 'b', 'c');

example.test.apply(null, ['a', 'b', 'c']);

Now, you won't get type checking on the arguments passed to apply - so if that is important then I recommend having two methods:

class Example {
    test(...strArray: string[]) {
        this.testWithArray(strArray);
    }

    testWithArray(strArray: string[]) {
        alert(strArray.length.toString());
    }
}

var example = new Example();

example.test('a', 'b', 'c');

example.testWithArray(['a', 'b', 'c']);

If you change an argument type in the final call here, you'll get type checking.

You can't overload a method with both because of the problem you describe in your question - so you can either use the TypeScript compiler to do the work (it will map the arguments for you) or do it all yourself if you want a single method for both. There is no magical way of getting both in this case.

Upvotes: 1

Related Questions