Машинопись статические классы



Я хотел перейти к TypeScript из традиционного JS, потому что мне нравится синтаксис C#-like.
Моя проблема заключается в том, что я не могу узнать, как объявить статические классы в TypeScript.



в C# я часто использую статические классы для организации переменных и методов, объединяя их в именованный класс, без необходимости устанавливать объект.
В vanilla JS я делал это с помощью простого объекта JS:



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


в TypeScript я бы предпочел использовать свой подход C-sharpy, но он кажется, что статические классы не существуют в ТС.
Каково соответствующее решение этой проблемы ?

651   11  

11 ответов:

TypeScript не является C#, поэтому вы не должны ожидать, что те же понятия C# в TypeScript обязательно. Вопрос в том, почему вы хотите, статические классы?

в C# статический класс-это просто класс, который не может быть подклассом и должен содержать только статические методы. C# не позволяет определять функции вне классов. Однако в TypeScript это возможно.

Если вы ищете способ поместить свои функции / методы в пространство имен (т. е. не глобальное), вы можете рассмотрите возможность использования модулей TypeScript, например

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

Так что вы можете получить доступ к M. f() внешне, но не s, и вы не можете расширить модуль.

посмотреть машинопись спецификация для более подробной информации.

определение статических свойств и методов класса, описанного в 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() - это статический (или "класс") способ.

абстрактные классы были первоклассным гражданином TypeScript с TypeScript 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

это один из способов:

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

__static_ctor здесь сразу же вызывается функция-выражение. Typescript выведет код для его вызова в конце сгенерированного класса.

Update: для универсальных типов в статических конструкторах, на которые больше не могут ссылаться статические члены, вам потребуется дополнительный шаг:

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 выше (очевидно).

я получил тот же случай использования сегодня(31/07/2018) и обнаружил, что это обходной путь. Он основан на моих исследованиях, и это сработало для меня. ожидание - для достижения следующего в 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();

это работает для меня. Если у кого есть другие предложения, пожалуйста, расскажите нам все !!! Спасибо...

см.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);

статические классы в таких языках, как C#, существуют, потому что нет других конструкций верхнего уровня для группировки данных и функций. В JavaScript, однако, они делают, и поэтому гораздо естественнее просто объявить объект, как вы это сделали. Чтобы более точно имитировать синтаксис класса, вы можете объявить методы следующим образом:

const myStaticClass = {
    property: 10,

    method() {

    }
}

один из возможных способов добиться этого-иметь статические экземпляры класса в другом классе. Например:

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 (как описано в исходном вопросе), но с преимуществами возможности добавления типизации TypeScript. Кроме того, он позволяет избежать необходимости добавлять "статический" перед всеми параметры в классе.

этот вопрос довольно устарел, но я хотел бы оставить ответ, который использует текущую версию языка. К сожалению, статические классы все еще не существуют в TypeScript, однако вы можете написать класс, который ведет себя аналогично с небольшими накладными расходами, используя частный конструктор, который предотвращает создание экземпляров классов извне.

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

этот фрагмент позволит вам использовать "статические" классы, похожие на аналог C# с единственным недостатком, что он все еще можно показать их изнутри. К счастью, хотя вы не можете расширить классы с частными конструкторами.

Я искал что-то подобное и наткнулся на что-то под названием Singleton Pattern.

ссылки: Синглтон Шаблон

Я работаю над классом BulkLoader для загрузки различных типов файлов и хотел использовать для этого одноэлементный шаблон. Таким образом, я могу загружать файлы из моего основного класса приложений и легко извлекать загруженные файлы из других классов.

Ниже приведен простой пример, как можно сделать результат менеджер для игры с помощью TypeScript и Одноэлементного шаблона.

класс 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() );

вы также можете использовать ключевое слово 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);
        }
    }
}

Comments

    Ничего не найдено.