TypeScript static classes

后端 未结 12 669
太阳男子
太阳男子 2020-12-04 13:34

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.

相关标签:
12条回答
  • 2020-12-04 14:12

    I was searching for something similar and came accross something called the Singleton Pattern.

    Reference: Singleton Pattern

    I am working on a BulkLoader class to load different types of files and wanted to use the Singleton pattern for it. This way I can load files from my main application class and retrieve the loaded files easily from other classes.

    Below is a simple example how you can make a score manager for a game with TypeScript and the Singleton pattern.

    class SingletonClass {

    private static _instance:SingletonClass = new SingletonClass();
    
    private _score:number = 0;
    
    constructor() {
        if(SingletonClass._instance){
            throw new Error("Error: Instantiation failed: Use SingletonDemo.getInstance() instead of new.");
        }
        SingletonClass._instance = this;
    }
    
    public static getInstance():SingletonClass
    {
        return SingletonClass._instance;
    }
    
    public setScore(value:number):void
    {
        this._score = value;
    }
    
    public getScore():number
    {
        return this._score;
    }
    
    public addPoints(value:number):void
    {
        this._score += value;
    }
    
    public removePoints(value:number):void
    {
        this._score -= value;
    }   }
    

    Then anywhere in your other classes you would get access to the Singleton by:

    var scoreManager = SingletonClass.getInstance();
    scoreManager.setScore(10); scoreManager.addPoints(1);
    scoreManager.removePoints(2); console.log( scoreManager.getScore() );
    
    0 讨论(0)
  • 2020-12-04 14:14

    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.

    0 讨论(0)
  • 2020-12-04 14:17

    With ES6 external modules this can be achieved like so:

    // privately scoped array
    let arr = [];
    
    export let ArrayModule = {
        add: x => arr.push(x),
        print: () => console.log(arr),
    }
    

    This prevents the use of internal modules and namespaces which is considered bad practice by TSLint [1] [2], allows private and public scoping and prevents the initialisation of unwanted class objects.

    0 讨论(0)
  • 2020-12-04 14:18

    I got the same use case today(31/07/2018) and found this to be a workaround. It is based on my research and it worked for me. Expectation - To achieve the following in TypeScript:

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

    I did this:

    //MyStaticMembers.ts
    namespace MyStaticMembers {
            class MyStaticClass {
               static property: number = 10;
               static myMethod() {...}
            }
            export function Property(): number {
               return MyStaticClass.property;
            }
            export function Method(): void {
               return MyStaticClass.myMethod();
            }
         }
    

    Hence we shall consume it as below:

    //app.ts
    /// <reference path="MyStaticMembers.ts" />
        console.log(MyStaticMembers.Property);
        MyStaticMembers.Method();
    

    This worked for me. If anyone has other better suggestions please let us all hear it !!! Thanks...

    0 讨论(0)
  • 2020-12-04 14:20

    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) { } 
      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.

    0 讨论(0)
  • 2020-12-04 14:22

    This is one way:

    class SomeClass {
        private static myStaticVariable = "whatever";
        private static __static_ctor = (() => { /* do static constructor stuff :) */ })();
    }
    

    __static_ctor here is an immediately invoked function expression. Typescript will output code to call it at the end of the generated class.

    Update: For generic types in static constructors, which are no longer allowed to be referenced by static members, you will need an extra step now:

    class SomeClass<T> {
        static myStaticVariable = "whatever";
        private ___static_ctor = (() => { var someClass:SomeClass<T> ; /* do static constructor stuff :) */ })();
        private static __static_ctor = SomeClass.prototype.___static_ctor();
    }
    

    In any case, of course, you could just call the generic type static constructor after the class, such as:

    class SomeClass<T> {
        static myStaticVariable = "whatever";
        private __static_ctor = (() => { var example: SomeClass<T>; /* do static constructor stuff :) */ })();
    }
    SomeClass.prototype.__static_ctor();
    

    Just remember to NEVER use this in __static_ctor above (obviously).

    0 讨论(0)
提交回复
热议问题