TypeScript静态类

Ray*_*jax 126 javascript static class typescript

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

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

var myStaticClass = {
    property: 10,
    method: function(){}
}
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*cus 156

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

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

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

module M {
    var s = "hello";
    export function f() {
        return s;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

有关更多详细信息,请参阅TypeScript 规范.

  • 这已被弃用.tslint也不允许你为模块和命名空间做到这一点.在这里阅读:https://palantir.github.io/tslint/rules/no-namespace/ (7认同)

Fen*_*ton 143

自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
Run Code Online (Sandbox Code Playgroud)

  • 在处理静态类时,这是最好的响应,我赞成这一点.`Singleton`用于同一类实例的共享内存模式.此外,静态类根据定义没有实例,因此如果客户端尝试初始化它,则必须抛出异常. (4认同)
  • 这是比将构造函数标记为私有更好的方法吗? (4认同)
  • 更新为使用 `abstract`!@KimchiMan - 好主意! (2认同)

Rob*_*sch 71

定义静态属性和类的方法在Typescript语言规范的 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); 
  } 
}
Run Code Online (Sandbox Code Playgroud)

其中Point.distance()是静态(或"类")方法.

  • 感谢您的评论.它描述了如何创建静态属性和方法,这些属性和方法结合在一起,可以创建具有数据和功能的类,而无需实例化.虽然不是特定的"静态类",但它确实满足了OP的JavaScript示例所描述的要求. (18认同)
  • 这显示了如何创建静态*方法*,它没有回答关于静态*类*的问题(除非真正的问题实际上是关于静态方法). (13认同)
  • @Simon_Weaver你不能在javascript中做什么?防止类被实例化?打字稿无论如何都不关心运行时,只要你在尝试做某些事情时遇到编译错误就不能让我们只需要它. (4认同)

Chr*_*vic 12

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

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

该代码片段将使您可以使用类似于C#对应对象的“静态”类,唯一的缺点是仍然可以从内部实例化它们。幸运的是,尽管您无法使用私有构造函数扩展类。


Jam*_*ins 7

这是一种方式:

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

__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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

只记得永远不要this__static_ctor上面使用(显然).


Yog*_*ogu 5

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

const myStaticClass = {
    property: 10,

    method() {

    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不觉得它扰乱了我的工作流程;相反,我发现在模块中使用无类 JavaScrpit 对象或仅使用普通函数和常量非常方便。但是,我也尽量避免使用全局状态,所以我很少需要像静态类变量这样的东西。 (5认同)

小智 5

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

var myStaticClass = {
    property: 10,
    method: function(){} 
}
Run Code Online (Sandbox Code Playgroud)

我这样做:

//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();
        }
     }
Run Code Online (Sandbox Code Playgroud)

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

//app.ts
/// <reference path="MyStaticMembers.ts" />
    console.log(MyStaticMembers.Property);
    MyStaticMembers.Method();
Run Code Online (Sandbox Code Playgroud)

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