I wanted to move to TypeScript from traditional JS because I like the C#-like syntax. My problem is that I can't find out how to declare static classes in TypeScript.

In C#, I often use static classes to organize variables and methods, putting them together in a named class, without needing to instatiate an object. In vanilla JS, I used to do this with a simple JS object:

var myStaticClass = {
    property: 10,
    method: function(){}
}

In TypeScript, I would rather go for my C-sharpy approach, but it seems that static classes don't exist in TS. What is the appropriate solution for this problem ?


Solution 1:

Abstract classes have been a first-class citizen of TypeScript since TypeScript 1.6. You cannot instantiate an abstract class.

Here is an example:

export abstract class MyClass {         
    public static myProp = "Hello";

    public static doSomething(): string {
      return "World";
    }
}

const okay = MyClass.doSomething();

//const errors = new MyClass(); // Error

Solution 2:

TypeScript is not C#, so you shouldn't expect the same concepts of C# in TypeScript necessarily. The question is why do you want static classes?

In C# a static class is simply a class that cannot be subclassed and must contain only static methods. C# does not allow one to define functions outside of classes. In TypeScript this is possible, however.

If you're looking for a way to put your functions/methods in a namespace (i.e. not global), you could consider using TypeScript's modules, e.g.

module M {
    var s = "hello";
    export function f() {
        return s;
    }
}

So that you can access M.f() externally, but not s, and you cannot extend the module.

See the TypeScript specification for more details.

Solution 3:

Defining static properties and methods of a class is described in 8.2.1 of the Typescript Language Specification:

class Point { 
  constructor(public x: number, public y: number) { 
    throw new Error('cannot instantiate using a static class');
  } 
  public distance(p: Point) { 
    var dx = this.x - p.x; 
    var dy = this.y - p.y; 
    return Math.sqrt(dx * dx + dy * dy); 
  } 
  static origin = new Point(0, 0); 
  static distance(p1: Point, p2: Point) { 
    return p1.distance(p2); 
  } 
}

where Point.distance() is a static (or "class") method.

Solution 4:

This question is quite dated yet I wanted to leave an answer that leverages the current version of the language. Unfortunately static classes still don't exist in TypeScript however you can write a class that behaves similar with only a small overhead using a private constructor which prevents instantiation of classes from outside.

class MyStaticClass {
    public static readonly property: number = 42;
    public static myMethod(): void { /* ... */ }
    private constructor() { /* noop */ }
}

This snippet will allow you to use "static" classes similar to the C# counterpart with the only downside that it is still possible to instantiate them from inside. Fortunately though you cannot extend classes with private constructors.