1

I would like to monkey patch the built in Date constructor in typescript, so when I call new Date(), I can define what the returned date will actually be.

I have tried starting off on this question: Date constructor monkey patch but in typescript you need to provide properties for the date constructor: (Type '() => any' is missing the following properties from type 'DateConstructor': parse, UTC, now), and you can't just define properties for a simple function.

Is there a way to do this? Thanks

fbede
  • 843
  • 9
  • 12

2 Answers2

2

I'm not sure it is possible to really override a type here, however you can always add needed properties / methods to the Date object:

interface Date {
  myExtraProperty: string
}

new Date().myExtraProperty; // works
Dmitriy
  • 2,742
  • 1
  • 17
  • 15
2

You would have to use a function constructor, since otherwise calls to Date() will throw:

const VanillaDate = Date;

declare global {
  interface DateConstructor {
    new(...args: number[]): Date;
  }
}

/** Monkey patches Date to where calls to Date.now() and new Date() will return another Date.  */
export function timeTravelTo(dateFactory: () => Date): void {
  timeTravelToNow();
  monkeyPatchDate(dateFactory());
}

export function timeTravelToNow(): void {
  Date = VanillaDate;
}

function monkeyPatchDate(date: Date): void {
  const newDate = function(...args: number[]) {
    if (args.length > 0) {
      return new VanillaDate(...args);
    }
    return new.target ? date : date.toString();
  };

  newDate.now = () => date.getTime();
  newDate.UTC = VanillaDate.UTC;
  newDate.parse = VanillaDate.parse;
  newDate.prototype = VanillaDate.prototype;

  Date = newDate as any;
}

blid
  • 971
  • 13
  • 22