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
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With