Now, args
is a rest parameter of a tuple type. How to make this constructor also accept arrays, which, when cast to tuple type, will result in a type that is specified in a said constructor?
Can it be done without manual assertion on construction, e.g.:
const args = [3, 5];
let vector = new Vector(...args as [number, number]);
or
const args: [number, number] = [3, 5];
let vector = new Vector(...args);
class Vector {
x: number;
y: number;
constructor(...args: [] | [number] | [number, number]) {
switch(args.length) {
case 0:
this.x = 0;
this.y = 0;
break;
case 1:
this.x = this.y = args[0];
break;
case 2:
this.x = args[0];
this.y = args[1];
break;
}
}
}
const args = [3, 5];
let vector = new Vector(...args);
Playground
EDIT: Considering @philipp-fritsche answer, what if I would add these overloads?
class Vector {
x: number;
y: number;
constructor();
constructor(xy: number);
constructor(x: number, y: number);
constructor(arg1?: number, arg2?: number) {
if(arg1 === undefined) {
this.x = this.y = 0;
} else if (arg2 == undefined) {
this.x = this.y = arg1;
} else {
this.x = arg1;
this.y = arg2;
}
}
}
const args = [1, 2];
let vector = new Vector(...args);
There is no benefit here in defining the parameters per rest.
class Vector {
x: number;
y: number;
constructor(x?: number, y?: number) {
this.x = x ?? 0
this.y = y ?? x ?? 0
}
}
const args = [3, 5];
let vector = new Vector(...args);
This works because the type infered for args is number[]
. And the elements 0
and 1
of number[]
are number | undefined
which matches the parameters for Vector
.
If you specify ...args: [] | [number] | [number, number]
, 0
, 1
or 2
arguments are allowed. But number[]
can have >=0
elements. So this violates your explicit type.
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