13

Is there anyhow anyway to add some static method to types like Date, String, Array, etc?

For example I want to add method today to Date class and in JavaScript I can simply add a property to it or maybe I use Object.defineProperty:

Date.today = function(){
    let date = new Date;
    date.setHours(0,0,0,0);
    return date;
}

Object.defineProperty(Date, 'today', { get() { ... }});

But I didn't find anyway to inform TypeScript about this new static member. Am I missing something or Did I google it the wrong way?

Morteza Tourani
  • 3,506
  • 5
  • 41
  • 48

2 Answers2

20

You have to augment the DateConstructor interface to add static properties:

declare global {
    interface DateConstructor {
        today: () => Date
    }
}   

Date.today = function(){
    let date = new Date;
    date.setHours(0,0,0,0);
    return date;
}

Similarly extend StringConstructor and ArrayConstructor for string and arrays. See declaration merging.

Saravana
  • 37,852
  • 18
  • 100
  • 108
  • if you'll be separating the type declaration and implementation. In practice, where do you put the implementing code? and how do you import it? – Jaime Sangcap Jun 25 '18 at 13:51
  • @JaimeSangcap You can use [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) to define your types in a custom `*.d.ts` file and [configure your `tsconfig.json`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types) to include them. – Saravana Jun 25 '18 at 15:20
  • thank you for answering. I also found this answer helpful https://stackoverflow.com/a/39877446/1730988 – Jaime Sangcap Jun 26 '18 at 07:01
  • What if the class I'm trying to add a method to is declared as var? Such as 'Response' https://github.com/microsoft/TypeScript/blob/226dd0b7bf5cb5e5bb4dc34ab0e8e14f408f3e20/lib/lib.dom.d.ts#L11554 – Jespertheend Oct 14 '22 at 12:35
1

I use this code to extend Object with static method. export class ObjectExtensions { }

declare global {
    interface ObjectConstructor {
        safeGet<T>(expresstion: () => T, defaultValue: T): T;
    }
}

Object.safeGet = function <T>(expresstion: () => T, defaultValue: T): T {
    try {
        const value = expresstion();
        if (value != null) return value;

    } catch (e) {
    }
    return defaultValue;
}

In main.ts you have to call this class like this

new ObjectExtensions();

And then you can use it like this:

Object.safeGet<number>(() => data.property.numberProperty);
Oleg Polezky
  • 1,006
  • 14
  • 13