如何正确定义 Date 子类的构造函数(typescript 4.1.3)?
Date对象的构造函数定义是这样的:
new(): Date;
new(value: number | string): Date;
new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
在我的代码中,我尝试指定这一点:
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)
*/
}
}
但这会导致超级调用中出现编译错误:
Argument of type 'string | number | undefined' is not assignable to parameter of type 'number'.
Type 'undefined' is not assignable to type 'number'.(2345)
如何定义构造函数参数,以便我可以使用原始 Date 对象具有的所有可能性来调用 super 并保持类型安全(尽可能)?
备注:
如果您想支持
Date
支持的所有签名,我认为除了分支(或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);
}
}
}
¹ (就其价值而言,我不认为你有 ,尽管你可能很想这样做。与
Array
或 Promise
不同,我不认为 Date
构造函数在任何地方被调用标准库)
您需要添加一些检查并针对每种情况调用适当的父构造函数:
constructor(
yearOrValue?: number | string, month?: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number
) {
if (yearOrValue === undefined) {
super()
} else if (month === undefined) {
super(yearOrValue)
} else if (typeof yearOrValue === 'number') {
super(yearOrValue, month, date, hours, minutes, seconds, ms)
}
}
你今天可以做这样的事情:
class MyDate extends Date {
constructor(...args: ConstructorParameters<typeof Date>) {
super(...args)
}
}
我遇到了同样的问题,并像这样实现它修复了所有 TS 错误:
class MyDate extends Date {
constructor();
constructor(value: number | string);
constructor(
year: number,
month: number,
date?: number,
hours?: number,
minutes?: number,
seconds?: number,
ms?: number,
);
constructor(
...args: [] | [number | string] | [number, number, number?, number?, number?, number?, number?]
) {
if (args.length === 0) {
super();
} else if (args.length === 1) {
super(args[0]);
} else {
super(...args);
}
}
}