如何为扩展 Date 的 class 定义构造函数?
How to define the constructor for a class that extends Date?
如何正确定义 Date (typescript 4.1.3) 的 child-class 的构造函数?
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)
*/
}
}
但这会导致 super 调用出现编译错误:
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 并保持类型安全(尽可能)?
备注:
- 这里是link到typescript playground example
- 这只是一些测试代码,在生产版本中我在构造函数中有更多代码
- 我想要一个适用于 class 的解决方案(即不会弄乱原型等)
如果您想支持 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
) {
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)
}
}
如何正确定义 Date (typescript 4.1.3) 的 child-class 的构造函数?
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)
*/
}
}
但这会导致 super 调用出现编译错误:
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 并保持类型安全(尽可能)?
备注:
- 这里是link到typescript playground example
- 这只是一些测试代码,在生产版本中我在构造函数中有更多代码
- 我想要一个适用于 class 的解决方案(即不会弄乱原型等)
如果您想支持 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
) {
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)
}
}