打字稿静态类(TypeScript static classes)

2019-07-03 13:06发布

我想是因为我喜欢C#语法式的从传统的JS移至打字稿。 我的问题是,我无法找出如何在打字稿声明静态类。

在C#中,我经常使用静态类来组织变量和方法,把它们放在一起在一个名为类,而无需instatiate的对象。 在香草JS,我用一个简单的JS对象做到这一点:

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

在打字稿,我宁愿去为我的C-夏氏的做法,但似乎静态类不存在TS。 什么是这个问题的合适的解决方案?

Answer 1:

打字稿不是C#,所以你不应该期待的C#中打字稿相同的概念必然。 问题是,为什么你要静态类?

在C#中的静态类是根本不能被继承,而且必须只包含静态方法的类。 C#不允许一个定义类之外的功能。 在打字稿这是可能的,但是。

如果你正在寻找一种方式来把你的函数/方法的命名空间(即不是全球性),你可以考虑使用打字稿的模块,如

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

所以,你可以访问MF()外部,而不是S,而不能扩展模块。

见打字稿规范的更多细节。



Answer 2:

因为打字稿1.6抽象类已经打字稿的一等公民。 你不能实例化一个抽象类。

下面是一个例子:

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

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

const okay = MyClass.doSomething();

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


Answer 3:

定义的静态属性和在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()是一个静态(或“类”)方法。



Answer 4:

这是一种方式:

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

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

更新:对于通用类型的静态构造函数,这是不再允许由静态成员引用,你现在需要一个额外的步骤:

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以上(明显)。



Answer 5:

这个问题是非常陈旧但我想离开,它利用语言的当前版本的答案。 不幸的是静态类仍然不存在打字稿但是你可以写,其行为只使用防止类实例化从外部私有构造一个小的开销相似的类。

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

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



Answer 6:

我得到了相同的用例今日(31/07/2018),并发现这是一种解决方法。 这是根据我的研究,它为我工作。 期望 -为了实现打字稿如下:

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

这为我工作。 如果任何人有其他更好的建议,请让我们都听到了! 谢谢...



Answer 7:

静态类如C#语言存在,因为没有其他顶层构建体组数据和功能。 在JavaScript中,然而,他们这样做,所以它是更自然,只是声明对象像你这样。 为了更紧密地模拟天生的类语法,你可以声明像这样的方法:

const myStaticClass = {
    property: 10,

    method() {

    }
}


Answer 8:

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

这是一种方式,以“假”静态构造函数。 这不是没有危险-见引用的CodePlex项目 。

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


Answer 9:

一种可能的方式实现这一目标是有另一个类中的一类的静态实例。 例如:

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.System.pageWidth = 1234;
Wrapper.DocLevel.totalPages = 10;

所以,你得到的的JavaScript对象类型的好处,而且具有能够添加打字稿打字的好处(如在原来的问题描述)。 此外,它避免了不得不在类的所有参数的前面添加“静态”。



Answer 10:

我正在寻找类似的东西,来到翻过一些所谓的Singleton Pattern

参考: Singleton模式

我工作的一个BulkLoader类加载不同类型的文件,并想使用Singleton模式吧。 这样我可以从我的主应用程序类加载文件,并从其他类轻松检索加载的文件。

下面是一个简单的例子,你如何可以使一个得分经理与打字稿和Singleton模式的游戏。

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

然后在你的其他类的任何地方,你会得到通过访问辛格尔顿:

 var scoreManager = SingletonClass.getInstance(); scoreManager.setScore(10); scoreManager.addPoints(1); scoreManager.removePoints(2); console.log( scoreManager.getScore() ); 


Answer 11:

您还可以使用关键字namespace来组织你的变量,类,方法等。 见DOC

namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }

    const lettersRegexp = /^[A-Za-z]+$/;
    const numberRegexp = /^[0-9]+$/;

    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }

    export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
        }
    }
}


文章来源: TypeScript static classes