Машинопись статические классы
Я хотел перейти к TypeScript из традиционного JS, потому что мне нравится синтаксис C#-like.
Моя проблема заключается в том, что я не могу узнать, как объявить статические классы в TypeScript.
в C# я часто использую статические классы для организации переменных и методов, объединяя их в именованный класс, без необходимости устанавливать объект.
В vanilla JS я делал это с помощью простого объекта JS:
var myStaticClass = {
property: 10,
method: function(){}
}
в TypeScript я бы предпочел использовать свой подход C-sharpy, но он кажется, что статические классы не существуют в ТС.
Каково соответствующее решение этой проблемы ?
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для упорядочивания переменных, классов, методов и так далее. Смотрите docnamespace 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