![](/img/trans.png)
[英]Index signature of type 'string' on interface not recognized (typescript)
[英]TypeScript interface signature “(): string”
在标准Node.js库的类型定义中,我找到了接口DateConstructor
的定义。
interface DateConstructor {
new(): Date;
new(value: number): Date;
new(value: string): Date;
new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
(): string;
readonly prototype: Date;
/**
* Parses a string containing a date, and returns the number of milliseconds between that date and midnight, January 1, 1970.
* @param s A date string
*/
parse(s: string): number;
/**
* Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date.
* @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.
* @param month The month as an number between 0 and 11 (January to December).
* @param date The date as an number between 1 and 31.
* @param hours Must be supplied if minutes is supplied. An number from 0 to 23 (midnight to 11pm) that specifies the hour.
* @param minutes Must be supplied if seconds is supplied. An number from 0 to 59 that specifies the minutes.
* @param seconds Must be supplied if milliseconds is supplied. An number from 0 to 59 that specifies the seconds.
* @param ms An number from 0 to 999 that specifies the milliseconds.
*/
UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;
now(): number;
}
declare const Date: DateConstructor;
它包含奇怪的定义(): string
。 如何在要实现此接口的类中定义它?
如果您认为此问题与我链接的另一个问题足够不同:
这个定义意味着类构造函数也是一个没有参数的可调用函数,当不使用new
调用时,该函数将返回字符串。 您不能使用ES2015或 更高版本的 class
并遵守规范,因为在没有new
情况下调用它时需要引发TypeError
。 相反,您可以返回一个检测到new
调用的函数,并添加了额外的属性以实现静态方法。
我将为您提供一个示例,其中为内置的Date
构造函数对象提供包装。 首先,让我们描述一下界面功能类似于或不带有new
关键字的部分:
interface FunctionalPartOfDateConstructor {
new(): Date;
new(value: number): Date;
new(value: string): Date;
new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
(): string;
}
现在让我们尝试实现这一部分:
const funcPart = function(valueOrYear?: number | string, month?: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date | string {
if (typeof new.target === 'undefined') {
// called as function
return Date();
}
if (typeof valueOrYear === 'undefined') {
// called as constructor with no arguments
return new Date();
}
if (typeof valueOrYear === 'string') {
// called as constructor with string value argument
return new Date(valueOrYear);
}
if (typeof month === 'undefined') {
// called as constructor with number value argument
return new Date(valueOrYear);
}
// called as constructor with year, month, date, etc arguments:
return new Date(valueOrYear, month, date, hours, minutes, seconds, ms);
} as FunctionalPartOfDateConstructor;
请注意,我使用new.target
来检测是否使用new
调用了该函数。 我认为,在针对ES5时,这可以编译为合理的内容。 并请注意,它必须弄清楚所有不同的过载签名之间的区别。
现在,我们可以通过将功能部分与实现静态方法的东西合并来制作完整的DateConstructor
实例:
const myDateConstructor: DateConstructor = Object.assign(funcPart, {
prototype: Date.prototype,
parse(s: string) {
return Date.parse(s);
},
UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number) {
return Date.UTC(year, month, date, hours, minutes, seconds, ms);
},
now() {
return Date.now();
}
})
如果需要,可以在TypeScript游乐场上尝试一下 。 希望能有所帮助; 祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.