TypeScript静态类

问题描述 投票:110回答:11

我想从传统的JS转向TypeScript,因为我喜欢类似C#的语法。我的问题是我无法找到如何在TypeScript中声明静态类。

在C#中,我经常使用静态类来组织变量和方法,将它们放在一个命名类中,而无需实例化对象。在vanilla JS中,我曾经用一个简单的JS对象做到这一点:

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

在TypeScript中,我宁愿选择我的C-sharp方法,但似乎TS中不存在静态类。这个问题的适当解决方案是什么?

javascript class static typescript
11个回答
143
投票

TypeScript不是C#,所以你不应该期望在TypeScript中使用相同的C#概念。问题是为什么你想要静态类?

在C#中,静态类只是一个不能被子类化的类,只能包含静态方法。 C#不允许在类之外定义函数。但是,在TypeScript中,这是可能的。

如果您正在寻找将函数/方法放在命名空间(即非全局)中的方法,可以考虑使用TypeScript的模块,例如:

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

因此,您可以从外部访问M.f(),但不能访问s,并且无法扩展模块。

有关更多详细信息,请参阅TypeScript specification


0
投票

我正在寻找类似的东西,并遇到了一种叫做qazxsw poi的东西。

参考:Singleton Pattern

我正在使用BulkLoader类来加载不同类型的文件,并希望使用Singleton模式。这样我就可以从我的主应用程序类加载文件,并轻松地从其他类中检索加载的文件。

下面是一个简单的示例,说明如何使用TypeScript和Singleton模式为游戏制作乐谱管理器。

class Singleton Class {

Singleton Pattern

然后在其他课程的任何地方,您都可以通过以下方式访问Singleton:

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;
}   }

-1
投票

您还可以使用关键字var scoreManager = SingletonClass.getInstance(); scoreManager.setScore(10); scoreManager.addPoints(1); scoreManager.removePoints(2); console.log( scoreManager.getScore() ); 来组织变量,类,方法等。见namespace

doc

117
投票

自TypeScript 1.6以来,抽象类一直是TypeScript的一等公民。您无法实例化抽象类。

这是一个例子:

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

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

const okay = MyClass.doSomething();

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

70
投票

Typescript Language Specification的8.2.1中描述了定义类的静态属性和方法:

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); 
  } 
}

其中Point.distance()是静态(或“类”)方法。


7
投票

这是一种方式:

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

这里的__static_ctor是一个立即调用的函数表达式。 Typescript将输出代码以在生成的类的末尾调用它。

更新:对于静态构造函数中的泛型类型,静态成员不再允许这些类型,您现在需要额外的步骤:

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

当然,在任何情况下,您都可以在类之后调用泛型类型的静态构造函数,例如:

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

请记住,永远不要在this上面使用__static_ctor(显然)。


7
投票

这个问题已经过时但我想留下一个利用当前语言版本的答案。不幸的是,TypeScript中仍然不存在静态类,但是您可以使用私有构造函数编写一个行为相似而且开销很小的类,该私有构造函数阻止从外部实例化类。

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

这段代码将允许您使用类似于C#对应的“静态”类,唯一的缺点是仍然可以从内部实例化它们。幸运的是,虽然你不能使用私有构造函数扩展类。


4
投票

我今天(2014年7月31日)得到了相同的用例,发现这是一个解决方法。这是基于我的研究,它对我有用。期望 - 在TypeScript中实现以下目标:

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

我这样做了:

//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();
        }
     }

因此我们将按如下方式使用它:

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

这对我有用。如果有人有其他更好的建议,请让我们都听到!谢谢...


3
投票

存在C#等语言的静态类,因为没有其他顶级构造来分组数据和函数。然而,在JavaScript中,他们这样做,因此像你一样声明一个对象更自然。为了更接近地模仿类语法,您可以声明如下方法:

const myStaticClass = {
    property: 10,

    method() {

    }
}

1
投票

http://www.basarat.com/2013/04/typescript-static-constructors-for.html

这是一种“伪造”静态构造函数的方法。它并非没有危险 - 请参阅referenced codeplex item

class Test {
    static foo = "orig";

    // Non void static function
    static stat() {
        console.log("Do any static construction here");
        foo = "static initialized";
        // Required to make function non void
        return null;
    }
    // Static variable assignment
    static statrun = Test.stat();
}

// Static construction will have been done:
console.log(Test.foo);

1
投票

实现此目的的一种可能方法是在另一个类中具有类的静态实例。例如:

class SystemParams
{
  pageWidth:  number = 8270;
  pageHeight: number = 11690;  
}

class DocLevelParams
{
  totalPages: number = 0;
}

class Wrapper
{ 
  static System: SystemParams = new SystemParams();
  static DocLevel: DocLevelParams = new DocLevelParams();
}

然后可以使用Wrapper访问参数,而无需声明它的实例。例如:

Wrapper.System.pageWidth = 1234;
Wrapper.DocLevel.totalPages = 10;

因此,您可以获得JavaScript类型对象的好处(如原始问题中所述),但具有能够添加TypeScript类型的好处。此外,它避免了必须在类中的所有参数前面添加“静态”。

© www.soinside.com 2019 - 2024. All rights reserved.