TypeScript 정적 클래스
기존 JS에서 TypeScript로 옮기고 싶었던 것은 C#과 같은 구문을 좋아하기 때문입니다.문제는 TypeScript에서 정적 클래스를 선언하는 방법을 찾을 수 없다는 것입니다.
C#에서는 정적 클래스를 사용하여 변수와 메서드를 정리하고 명명된 클래스로 정리하는 경우가 많습니다.오브젝트를 인스톨 할 필요는 없습니다.바닐라 JS에서는 단순한 JS 오브젝트로 이 작업을 수행했습니다.
var myStaticClass = {
property: 10,
method: function(){}
}
TypeScript에서는 C-Sharpy 방식을 택하고 싶지만, TS에는 스태틱 클래스가 존재하지 않는 것 같습니다.이 문제에 대한 적절한 해결책은 무엇입니까?
추상 클래스는 TypeScript 1.6 이후 TypeScript의 1등급 시민입니다.추상 클래스는 인스턴스화할 수 없습니다.
다음은 예를 제시하겠습니다.
export abstract class MyClass {
public static myProp = "Hello";
public static doSomething(): string {
return "World";
}
}
const okay = MyClass.doSomething();
//const errors = new MyClass(); // Error
TypeScript는 C#이 아니기 때문에 반드시 TypeScript와 같은 개념의 C#을 기대할 필요는 없습니다.문제는 왜 정적 클래스를 원하느냐는 것입니다.
C#에서 스태틱클래스는 단순히 서브클래스가 불가능한 클래스이며 스태틱 메서드만 포함해야 합니다.C#에서는 클래스 이외의 함수를 정의할 수 없습니다.단, TypeScript에서는 가능합니다.
함수/메서드를 네임스페이스(글로벌하지 않음)에 배치하는 방법을 찾고 있다면 TypeScript의 모듈을 사용하는 것을 고려해 보십시오.
module M {
var s = "hello";
export function f() {
return s;
}
}
외부에서는 M.f()에 액세스 할 수 있지만,s에는 액세스 할 수 없습니다.모듈을 확장할 수 없습니다.
자세한 내용은 TypeScript 사양을 참조하십시오.
클래스의 정적 속성과 메서드의 정의는 Typescript Language Specification의 8.2.1에 설명되어 있습니다.
class Point {
constructor(public x: number, public y: number) {
throw new Error('cannot instantiate using a static class');
}
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 Specification으로 업데이트 되었습니다.https://github.com/Microsoft/TypeScript/issues/15711에 따르면 Typescript에 대한 정식 사양은 현재 존재하지 않으며 존재하지도 않습니다.
이 질문은 꽤 오래되었지만 나는 현재 버전의 언어를 활용한 답변을 남기고 싶었다.안타깝게도 TypeScript에는 정적 클래스가 아직 없지만 외부로부터의 클래스 인스턴스화를 방지하는 프라이빗 컨스트럭터를 사용하여 약간의 오버헤드만으로 유사한 동작을 하는 클래스를 작성할 수 있습니다.
class MyStaticClass {
public static readonly property: number = 42;
public static myMethod(): void { /* ... */ }
private constructor() { /* noop */ }
}
이 스니펫을 사용하면 C#의 대응 클래스와 유사한 스태틱클래스를 사용할 수 있습니다.단, 이러한 클래스는 내부에서 인스턴스화할 수 있다는 단점이 있습니다.다행히 개인 컨스트럭터로는 클래스를 확장할 수 없습니다.
오늘(2018년 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();
이건 나한테 효과가 있었어.더 좋은 제안이 있으면 모두 들려주세요!!!감사합니다.
한 가지 방법이 있습니다.
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.___static_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
□(표준)
데이터 및 함수를 그룹화하는 다른 최상위 구조가 없기 때문에 C#과 같은 언어의 정적 클래스가 존재합니다.그러나 JavaScript에서는 이러한 기능이 있기 때문에 사용자처럼 개체를 선언하는 것이 훨씬 더 자연스럽습니다.클래스 구문을 보다 정확하게 모방하기 위해 다음과 같은 메서드를 선언할 수 있습니다.
const myStaticClass = {
property: 10,
method() {
}
}
ES6 외부 모듈에서는 다음과 같이 할 수 있습니다.
// privately scoped array
let arr = [];
export let ArrayModule = {
add: x => arr.push(x),
print: () => console.log(arr),
}
이를 통해 TSLint [1][2]에 의해 잘못된 관행으로 간주되는 내부 모듈 및 네임스페이스 사용을 방지하고 프라이빗 및 퍼블릭 스코핑을 허용하며 불필요한 클래스 객체의 초기화를 방지합니다.
http://www.basarat.com/2013/04/typescript-static-constructors-for.html 를 참조해 주세요.
이것은 정적 생성자를 '가짜'하는 방법입니다.위험성이 없는 것은 아닙니다.참조된 코드플렉스 항목을 참조하십시오.
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);
이를 실현하는 방법 중 하나는 클래스의 스태틱인스턴스를 다른 클래스 내에 두는 것입니다.예를 들어 다음과 같습니다.
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를 사용하여 파라미터에 액세스할 수 있습니다.예를 들어 다음과 같습니다.
Wrapper.System.pageWidth = 1234;
Wrapper.DocLevel.totalPages = 10;
따라서 JavaScript type 객체의 장점(원래 질문에서 설명한 바와 같이)을 얻을 수 있지만 TypeScript type을 추가할 수 있다는 장점이 있습니다.또한 클래스의 모든 파라미터 앞에 'static'을 추가할 필요가 없습니다.
공개 정적 읽기 전용 구성원과 함께 추상 클래스를 사용하여 원하는 것과 매우 유사한 작업을 수행할 수 있습니다.내 생각에 당신은 이런 걸 찾고 있는 것 같은데struct
C# 또는 C/C++에서 작은 데이터를 정리합니다.
추상 수업의 멋진 점은
- 인스턴스화할 수 없습니다.
- 이것들은, 및 에서만 취득할 수 있습니다.
- 이 경우 정의된 일부 또는 모든 방법에 대한 기본 구현을 제공할 수 있습니다.
심지어 이 기술을 사용하여 어느 정도 모방할 수 있습니다.enum
(예를 들어, 이러한 속성을 켤 수는 없지만) 문자열이나 숫자 이상의 속성을 가질 수 있습니다.
// you can omit the public keyword because it's the default in TS, I left it here for clarity
export abstract class RequestTypes {
public static readonly All = 'All types';
public static readonly Partners = 'Partners';
public static readonly Articles = 'Articles';
}
선호하는 방법은 const 객체(주로 enum 대신)를 사용하는 것입니다.
const RequestTypes2 = {
All: 'All types',
Partners: 'Partners',
Articles: 'Articles',
} as const; // need the "const" to force the property types to be string literal types (hover RequestTypes2 to see!)
// now you can do this (hover AllowedRequestTypes to see the inferred type)
type AllowedRequestTypes = typeof RequestTypes2[keyof typeof RequestTypes2];
function doRequest(requestType: AllowedRequestTypes) {
}
// these should work
doRequest('Partners');
doRequest(RequestTypes2.All);
doRequest(RequestTypes.Articles); // the property's type is "Articles" (string literal type)
// this fails
doRequest('Incorrect');
이 TS 놀이터를 확인하십시오.
비슷한 걸 찾다가 우연히 발견했어요Singleton Pattern
.
레퍼런스:싱글턴 패턴
여러 종류의 파일을 로드하기 위해 BulkLoader 클래스에서 작업하고 있는데 싱글톤 패턴을 사용하고 싶었습니다.이렇게 하면 주 응용 프로그램 클래스에서 파일을 로드하고 다른 클래스에서 로드된 파일을 쉽게 가져올 수 있습니다.
다음은 TypeScript와 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; } }
그 외의 클래스에서는, 다음의 방법으로 싱글톤에 액세스 할 수 있습니다.
var scoreManager = SingletonClass.getInstance(); scoreManager.setScore(10); scoreManager.addPoints(1); scoreManager.removePoints(2); console.log( scoreManager.getScore() );
키워드를 사용할 수도 있습니다.namespace
변수, 클래스, 메서드 등을 정리합니다.문서 참조
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에서 클래스를 만들 수 있습니다.
export class Coordinate {
static x: number;
static y: number;
static gradient() {
return y/x;
}
}
인스턴스화 없이 해당 속성 및 메서드를 참조할 수 있으므로 다음과 같이 하십시오.
Coordinate.x = 10;
Coordinate.y = 10;
console.log(`x of ${Coordinate.x} and y of ${Coordinate.y} has gradient of ${Coordinate.gradient()}`);
보간 구문 ${}과(와) 함께 backticks "를 사용하는 Fyi는 코드와 텍스트 :-를 쉽게 혼합할 수 있습니다.
언급URL : https://stackoverflow.com/questions/13212521/typescript-static-classes
'sourcecode' 카테고리의 다른 글
스프링 부츠를 사용한 심플한 임베디드 Kafka 테스트 예시 (0) | 2023.02.15 |
---|---|
스프링: @ResponseBody "ResponseEntity"를 반환합니다. (0) | 2023.02.15 |
2개의 JSON 객체 비교 (0) | 2023.02.15 |
Spring MVC REST 컨트롤러에서 HTTP 헤더 정보에 액세스하려면 어떻게 해야 합니까? (0) | 2023.02.15 |
C#을 사용하여 csv 파일을 json으로 변환 (0) | 2023.02.15 |