16

I'm thinking about but can't find any reason to use static methods (and especially private static) in a TypeScript class. Am I missing something? I'm asking this question because I saw code like this:

class Abc {

  public someMethod() {
     Abc.myMethod();
  }

  private static myMethod() {
     ...
  }
} 

P.S. For those who try to explain me difference between static and non-static methods and what is private method. I know these perfectly well thanks to my many years background in C#. If you read question carefully - it was about using these in TypeScript.

Harald
  • 4,575
  • 5
  • 33
  • 72
andrey.shedko
  • 3,128
  • 10
  • 61
  • 121
  • 5
    [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) is a constructor with static methods like `Array.from()` and `Array.isArray()`. Do you understand why those methods are static and not instance methods like `Array.prototype.map()` and `Array.prototype.filter()`? – jcalz Sep 24 '18 at 14:35
  • 1
    Private methods and properties are there for the use of the implementer of a class, and not for the use of the consumer of the class. Do you understand why someone would not want to expose implementation details of a class to a consumer of a class? – jcalz Sep 24 '18 at 14:36
  • @jcalz, all these things are obvious, any real life use cases? – andrey.shedko Sep 24 '18 at 14:44
  • 1
    We must be talking past each other. What is not "real life" about `Array.from()`? If the reasons I gave for using private methods and static methods are "obvious", then the answer to your question is obvious. – jcalz Sep 24 '18 at 15:08
  • 1
    I'm not sure if this is what @andrey.shedko had in mind, but to me the alternative to static methods is not instance methods, it's a plain function your class closes over. You can make these "private" by simply not exporting them. Here's an example: https://gist.github.com/mkantor/869393fb4e6f37d237e4853949862246 – Matt Kantor Nov 12 '18 at 18:26

4 Answers4

12

The main difference between a static method/property and a non-static one is that: at the memory level, a portion of the memory will be created for the static fields, which will be shared across all objects in the class. So it works in C # or Java.

For javascript this behavior was implemented In ES6+. But for earlier versions of Ecma Scripts typescript emulates this case.

In your case method myMethod() can be used as a way to hide the complex resource-intensive functionality of the not tied from a specific instance of the class and hidden from the end user.

See this code:

class A {
    protected _p: string;
    constructor() { 
        this._p = "A";
    }
    public someMethod(value: string) {
        A.myMethod(this._p + value);
    }
    private static myMethod(p:string) {
        console.log(p);
    }
} 

class B extends A {
    constructor() { 
        super();
        this._p = "B";
    }
}

var a1 = new A();
a1.someMethod("_1");
var a2 = new A();
a2.someMethod("_2");
var b1 = new B();
b1.someMethod("_1");
andrey.shedko
  • 3,128
  • 10
  • 61
  • 121
Noneme
  • 816
  • 6
  • 22
9

I personally like to use private static methods to indicate a pure function. Then you absolutely know that such a method will never mutate the object's state.

Implementing functional programming whenever possible within the object oriented programming paradigm creates more side-effect free code that ultimately has lower coupling. This leads to code that is less prone to object state bugs, regression bugs, and that is generally easier to understand.

Here's a very simple example:

interface DatabaseFoo {
    size: number;
    color: string;
}

class Foo {
    private static toDatabaseFoo(
        uid: string,
        color: number,
        length: number,
        width: number
    ): DatabaseFoo {
        let convertedData: DatabaseFoo;

        // Perform object specific data cleaning and/or transformations

        return convertedData;
    }

    private color: number;
    private length: number;
    private uid: string;
    private width: number;

    saveToPersistence(): void {
        const databaseFoo = Foo.toDatabaseFoo(
            this.uid,
            this.color,
            this.length,
            this.width
        );
        const jsonFoo = JSON.stringify(databaseFoo);

        // Save to persistence
    }
}
Tom Daniel
  • 183
  • 1
  • 9
  • 2
    I very much agree with your statement `I personally like to use private static methods to indicate a pure function.` I also do this myself, even for private members, to communicate it is a pure, side-effect free function. – RcoderNY Sep 27 '21 at 08:03
  • 1
    Should be the accepted answer. It just leaves open the (not asked by OP) quesition why not just use file-scope, non-exported functions instead of static functions inside the class? <- Here I am assuming a file containing only one class. If many classes are in one file, scoping a private static function inside a class of course makes sense. – Harald Feb 26 '22 at 10:19
  • @Harald IMO, this is a very good point and a completely acceptable alternative in situations where a file only contains one class. I would argue however that if you have other files that contain multiple classes, then it's best to stick to a single convention throughout your codebase. In that case you may prefer to keep all class related pure functions as private static methods. – Tom Daniel Sep 07 '22 at 22:09
1

You will use private methods just within your class. It is not accessible from outside. The same as Java, etc.. Same for private static.

Static means that you want to access the method over the class name without creating an object (instantiation). It is also accessible from an outer class. Without static you need to create an object.

class Abc {

  public someMethod() { 
     Abc.myMethod(); // Here you are able to access the static method myMethod because you are in the same class. It is not possible to access myMethod from another class directly. But someMethod() you can access directly which takes e.g. the data from myMethod();
  }

  private static myMethod() { // It is private and only accessible within the class and static therefore you can access it over the class name Abc.myMethod()
     ...
  }
} 

I hope it helps

Moni Ta
  • 51
  • 5
  • 5
    Thanks for the answer, but this explain nothing about the reason or possible use case, actually. – andrey.shedko Sep 24 '18 at 14:18
  • One use case could be a factory pattern. The methods are static and accessible from other classes. If the method is private you can not use these methods from outside. The main word for you could be reusable code and maintability. Private is also used for security reasons – Moni Ta Sep 24 '18 at 14:23
  • Why would this "help?" It completely ignores the actual question being asked. – sovemp Jun 07 '22 at 18:43
0

I am not sure myself as I stumbled upon this question while searching for exactly how static members/methods will be used in TypeScript. One use case I can think of just on top of my head is something like an item renderer in a grid.

Let us say you have a renderer component class which takes in raw number and formats it with thousand separators and CCY symbols or something like that. So you have this method which takes a raw number 12345 and gives back $12,345.00

You are using this renderer on a grid on each cell so you don't want the formatter function to be created for each row. You would make it static so all instances can use this once for formatting. Then you also have something proprietary about this formatting and you don't want anyone else to use this formatting. Or just that you want to be free around making implementation changes of this method in the future and not want any other classes elsewhere in the application to use a readymade formatting because it is just lying around outside of the class. Then you make it private.

That is for the use case, am I making sense?

Having said that, I am not sure how TS would translate that in JS to retain its privateness.

Harshal
  • 485
  • 7
  • 16
  • I would prefer to pass formatter function as an argument for this purpose. – andrey.shedko Aug 26 '21 at 09:05
  • But where will you be keeping it? Considering this formatting function is specific to this renderer and not to be used elsewhere in the application? – Harshal Aug 26 '21 at 13:34