Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to Date prototype and keep other methods #7726

Closed
mbakker96 opened this issue Mar 29, 2016 · 11 comments
Closed

Add function to Date prototype and keep other methods #7726

mbakker96 opened this issue Mar 29, 2016 · 11 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@mbakker96
Copy link

Hello,

I want to add a function to the Date prototype. I want to add a weekNumber function to it that returns the number of the week.

I wan to create make it on the typescript way so much as posible.

This is the prototype function:

Date.prototype.getWeekNumber()
    var d: Date = new Date(+this);
    d.setHours(0, 0, 0);
    d.setDate(d.getDate() + 4 - (d.getDay() || 7));
    return Math.ceil((((d - new Date(d.getFullYear(), 0, 1)) / 8.64e7) + 1) / 7);
};

I created a interface but the problem was that he removed all the functions of the Date and becease of that my IDE was giving an error that the functions are not existing.

Does someknow how to do it by the right way?`

@mhegazy
Copy link
Contributor

mhegazy commented Mar 29, 2016

// Extend the type, and declare the new function
interface Date {
    getWeekNumber(): number;
}

// Add the implementation
Date.prototype.getWeekNumber = function () {
....
};

var x = new Date();


x.getWeekNumber();

@mhegazy mhegazy added the Question An issue which isn't directly actionable in code label Mar 29, 2016
@mhegazy mhegazy closed this as completed Mar 29, 2016
@mbakker96
Copy link
Author

The problem with this is that all the methods of the Date are not available anymore

@RyanCavanaugh
Copy link
Member

See https://github.com/Microsoft/TypeScript/wiki/FAQ#why-did-adding-an-import-or-export-modifier-break-my-program . The interface Date { declaration needs to not be an a module file.

@mbakker96
Copy link
Author

What is the right way to do it? @RyanCavanaugh

@RyanCavanaugh
Copy link
Member

Take the interface Date { declaration and put it in a .d.ts file that doesn't have any top-level import or export statements in it, then reference that .d.ts file in your compilation (either through a /// <reference or by adding it to the list of files on the commandline or tsconfig.json)

@mhegazy
Copy link
Contributor

mhegazy commented Mar 31, 2016

if you are using TS 1.8.5 or higher, consider using:

declare global {
    interface Date {
        myMethod(): number;
    }
}

see https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#augmenting-globalmodule-scope-from-modules for more details.

@gfrSE
Copy link

gfrSE commented Jul 22, 2016

How to access the "date object" ?
Or whatever object i am extending..

Using this will return the first exported object in that file?!

... some angular2 stuff here ...


// DATE EXTENSIONS
// ================

declare global {
  interface Date {
    isToday(): boolean;
  }
}

Date.prototype.isToday = (): boolean => {
  let today = new Date();
  console.log(this); // WILL RETURN FIRST EXPORTED ANGULAR2 OBJECT IN THIS FILE
  return today.getFullYear() === this.getFullYear() && today.getMonth() === this.getMonth() && today.getDate() === this.getDate();
};

same behavior on top of the file.

EDIT:

tried in a separate file:

date.extensions.ts

export {}

// DATE EXTENSIONS
// ================

declare global {
   interface Date {
      addDays(days: number, useThis?: boolean): Date;
      isToday(): boolean;
      clone(): Date;
      isAnotherMonth(date: Date): boolean;
      isWeekend(): boolean;
      isSameDate(date: Date): boolean;
   }
}

Date.prototype.addDays = (days: number): Date => {
   if (!days) return this;
   console.log(this);
   let date = this;
   date.setDate(date.getDate() + days);

   return date;
};

Date.prototype.isToday = (): boolean => {
   let today = new Date();
   return this.isSameDate(today);
};

Date.prototype.clone = (): Date => {
   return new Date(+this);
};

Date.prototype.isAnotherMonth = (date: Date): boolean => {
   return date && this.getMonth() !== date.getMonth();
};

Date.prototype.isWeekend = (): boolean => {
   return this.getDay() === 0 || this.getDay() === 6;
};

Date.prototype.isSameDate = (date: Date): boolean => {
   return date && this.getFullYear() === date.getFullYear() && this.getMonth() === date.getMonth() && this.getDate() === date.getDate();
};

// EOF

date-picker.component.ts

.. imports ..

import './date.extensions';

.. angular2 stuff ..
.. trying to use the extended methods in here ! ..

see the following error message in console:

Uncaught TypeError: date.getDate is not a functionDate.addDays @ date.extensions.ts:21(anonymous function) @ month-view.component.ts:39ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ ng_zone_impl.ts:61ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423

and logging this inside the addDays function prints out the window-object ..

@mhegazy
Copy link
Contributor

mhegazy commented Jul 22, 2016

Lambda expressions do not have a this binding. they inherit the one from the containing scope. in this case, it is the module. This is the ES2015 semantics of lambdas.

use a function expression instead. e.g.:

Date.prototype.isToday = function (): boolean {
 ... 
};

@mxii
Copy link

mxii commented Jul 23, 2016

@mhegazy Thanks alot!!

Took me many hours to play around but no success..
Thanks, works like a charm!

@amsakanna
Copy link

I figured the lambda issue already. Still didn't work. But thank you gfrSE. Adding export {} on top resolved my issue.

@xtianus79
Copy link

xtianus79 commented Jul 21, 2017

@mhegazy do you have documentation on that... it is great informaiton and would like to read more up on it.

Lambda expressions do not have a this binding. they inherit the one from the containing scope. in this case, it is the module. This is the ES2015 semantics of lambdas.
use a function expression instead. e.g.:
Date.prototype.isToday = function (): boolean {
...
};

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

7 participants