Javascript/Typescript-使用新方法扩展日期对象



我正在尝试扩展Date对象以添加有用的方法。

根据W3Schools的说法,这应该有效:

Date.prototype.removeTime = () => {
// some awesome code to remove the timestamp
}

但是Typescript抱怨removeTime不是Date对象的已知属性。(技术上是正确的(

所以,我尝试了这个:

Object.defineProperty(Date.prototype, "removeTime", {
enumerable: false,
configurable: false,
writable: false,
value: function() {
// Do some magic
return null;
}
});

但是,当在代码中使用它时:

类型"Date"上不存在属性"removeTime">

我不明白,因为我这样做是为了向数组原型添加一个方法,比如:

Object.defineProperty(Array.prototype, "unique", {
enumerable: false,
configurable: false,
writable: false,
value: function() {
const a = this.concat();
for (let i = 0; i < a.length; ++i) {
for (let j = i + 1; j < a.length; ++j) {
if (a[i] === a[j]) {
a.splice(j--, 1);
}
}
}
return a;
}
});

这是有效的,我可以在代码中使用它,Typescript没有抱怨。

我在这里错过了什么?为什么它对Array有效而对Date无效?

编辑:在阅读了评论之后,我决定采用一种方法:

removeTimeFromDate(date: Date): Date {
return new Date(date.getFullYear(), date.getMonth(), date.getDay());
}

这里有两种不同的东西:

  1. 添加运行时方法

  2. 添加类型信息

您所做的是添加运行时内容,但不是更新类型。

你可以添加这样的类型信息:

interface Date {
removeTime(): Date;
}

这增加了Date接口。

(此外,在添加运行时方法时,请使用defineProperty方法,而不是带有箭头函数的赋值。(

下面是一个完整的例子:

// Type
interface Date {
removeTime(): Date;
}
// Runtime
Object.defineProperty(Date.prototype, "removeTime", {
enumerable: false,   // This is the default, you can leave it off if you like
configurable: true,  // Normally, method properties are configurable
writable: true,      // Normally, method properties are writable
value: function() {
// Do some magic
this.setHours(0, 0, 0, 0);
return this;
}
});
let d = new Date();
console.log(d.toISOString());
d.removeTime();
console.log(d.toISOString());

在操场上


FWIW,关于扩展内建的几个注意事项:

  • 这通常不是将在您不直接控制的项目中使用的代码的最佳实践(您正在编写的用于他人项目的库代码等(
  • 通常最好使用defineProperty来定义不可枚举的属性(不过通常是可写和可配置的(
  • 选择真正特定于您的项目的名称,这样,如果在规范的后面添加内建,您的名称就不太可能被使用。只是有可能在某个时候将removeTime方法添加到Date中(尽管这不太可能(,但不可能添加myRemoveTime方法

相关内容

  • 没有找到相关文章

最新更新