Reputation: 2036
Is there any way (special syntax) to apply something like rest
parameters to templates in TypeScript?
If question is unclear then take a look at below example and comments.
Question is - can I apply here something like rest ...Types
:
function mixIt<A, B> (a: A, b: B): A & B;
function mixIt<A, B, C>(a: A, b: B, c: C): A & B & C;
/*
* ??
* If I would like to add D, E, F, etc, do I have to overwrite it like above?
*/
function mixIt<A, B, C>(...args: any[]): any{
let mixin = <A & B & C> {};
args.forEach( obj => {
for(let key in obj) {
if( ! mixin.hasOwnProperty(key) ) {
(<any>mixin)[key] = obj[key];
}
}
});
return mixin;
}
FYI - error detection is as expected:
class X {x: number = 7;}
class Y {y: string = 'ok';}
class Z {z: boolean = false;}
let x = new X;
let y = new Y;
let z = new Z;
let xy = mixIt(x, y);
let xyz = mixIt(x, y, z);
xyz.z; // Ok;
xy.z; // Error - as expected. VS Code editor also highlights it
Upvotes: 6
Views: 3046
Reputation: 249506
Edit Since the original answer typescript has added support for tuples in rest parameters in 3.0. With this we can achieve the desired result without all the overloads:
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
function mixIt<T extends any[]>(...args: T): UnionToIntersection<T[number]>{
let mixin: any = {};
args.forEach( obj => {
for(let key in obj) {
if( ! mixin.hasOwnProperty(key) ) {
mixin[key] = obj[key];
}
}
});
return mixin;
}
Original answer
There is no way to currently have a variable number of type parameters, there is a proposal on this.
The only way to currently do this is to add as many signatures to the functions as needed, so in your case this would be:
function mixIt<A, B> (a: A, b: B): A & B;
function mixIt<A, B, C>(a: A, b: B, c: C): A & B & C;
function mixIt<A, B, C, D>(a: A, b: B, c: C, d: D): A & B & C & D;
function mixIt<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E): A & B & C & D & E;
function mixIt<A, B, C, D, E, F>(a: A, b: B, c: C, d: D, e: E, f: F): A & B & C & D & E &F ;
// Private signature
function mixIt(...args: any[]): any{ // no need for this to be generic
let mixin: any = {};
args.forEach( obj => {
for(let key in obj) {
if( ! mixin.hasOwnProperty(key) ) {
mixin[key] = obj[key];
}
}
});
return mixin;
}
Upvotes: 9