How can I correctly define the constructor for a child-class of Date (typescript 4.1.3)?
The constructor definition of the Date object is this:
new(): Date;
new(value: number | string): Date;
new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
in my code, I try to specify this:
class MyDate extends Date {
// overloads copied from DateConstructor
constructor();
constructor(value: number | string);
constructor(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number);
// constructor impl
constructor(
yearOrValue?: number | string, month?: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number
) {
super(yearOrValue, month, date, hours, minutes, seconds, ms);
/* ^^^^^^^^^^^
Argument of type 'string | number | undefined' is not assignable to parameter of type 'number'.
Type 'undefined' is not assignable to type 'number'.(2345)
*/
}
}
but this causes a compile error in the super call:
Argument of type 'string | number | undefined' is not assignable to parameter of type 'number'.
Type 'undefined' is not assignable to type 'number'.(2345)
How can I define the constructor parameters, so that I can call super with all possibilities that the original Date object has and keep type-safety (as much as possible)?
Notes:
If you want to support all of the signatures that Date
supports,¹ I don't think you have much choice other than branching (or punting):
class MyDate extends Date {
// overloads copied from DateConstructor
constructor();
constructor(value: number | string);
constructor(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number);
// constructor impl
constructor(
yearOrValue?: number | string,
month?: number,
date?: number,
hours?: number,
minutes?: number,
seconds?: number,
ms?: number
) {
if (typeof yearOrValue === "undefined") {
super();
} else if (typeof month === "undefined") {
super(yearOrValue);
} else {
// consider an assertion here that `yearOrValue` is a number
super(yearOrValue as number, month, date, hours, minutes, seconds, ms);
}
}
}
¹ (For what it's worth, I don't think you have to, though you may well want to. Unlike Array
or Promise
, I don't think the Date
constructor is called anywhere in the standard library)