typescript에서 클래스 상수를 구현하는 방법은 무엇입니까?


429

TypeScript에서는 const키워드를 사용하여 클래스 속성을 선언 할 수 없습니다. 이렇게하면 "클래스 멤버는 'const'키워드를 가질 수 없습니다."라는 오류가 발생합니다.

코드에서 속성을 변경해서는 안된다는 것을 명확하게 표시해야합니다. 속성이 선언되면 속성에 새 값을 할당하려고하면 IDE 또는 컴파일러에서 오류가 발생하기를 원합니다. 너희들은 어떻게 이것을 달성합니까?

현재 읽기 전용 속성을 사용하고 있지만 Typescript (및 JavaScript)를 처음 사용하고 더 좋은 방법이 있는지 궁금합니다.

get MY_CONSTANT():number {return 10};

typescript 1.8을 사용하고 있습니다. 제안?

추신 : 나는 지금 typescript 2.0.3을 사용하고 있으므로 David의 대답을 받아 들였습니다.

답변:


651

TypeScript 2.0에는 readonly수정자가 있습니다 .

class MyClass {
    readonly myReadOnlyProperty = 1;

    myMethod() {
        console.log(this.myReadOnlyProperty);
        this.myReadOnlyProperty = 5; // error, readonly
    }
}

new MyClass().myReadOnlyProperty = 5; // error, readonly

생성자에서 할당을 허용하기 때문에 상수는 아니지만, 그다지 큰 문제는 아닙니다.

대체 솔루션

대안은 static키워드를 readonly다음 과 함께 사용하는 것 입니다 .

class MyClass {
    static readonly myReadOnlyProperty = 1;

    constructor() {
        MyClass.myReadOnlyProperty = 5; // error, readonly
    }

    myMethod() {
        console.log(MyClass.myReadOnlyProperty);
        MyClass.myReadOnlyProperty = 5; // error, readonly
    }
}

MyClass.myReadOnlyProperty = 5; // error, readonly

이는 생성자에서 할당 할 수없고 한 곳에만 존재한다는 이점이 있습니다.


31
클래스 외부에서 속성에 액세스하려면 추가해야합니다 export전에 키워드를 class뿐만 아니라 public static전과 readonly키워드. 여기를 참조하십시오 : stackoverflow.com/a/22993349
cbros2008

질문. 클래스 자체에서 readOnly 속성을 사용하기 위해 클래스 이름이 필요한 이유는 확실하지 않습니까? 'MyClass.myReadonlyProperty'
Saiyaff 파 루크

@SaiyaffFarouk 귀하의 질문을 이해하면 대답은 정적 속성이 클래스의 인스턴스가 아니라 클래스의 일부로 존재한다는 것입니다. 따라서 클래스 인스턴스를 포함하는 변수가 아닌 클래스 이름을 사용하여 액세스합니다.
JeffryHouser

1
export(외부 모듈) 및 public키워드는이 질문 / 답변 관련이없는,하지만 명확성의 주제에, 나는 개인적으로 키워드가 존재하지 않는 경우 회원이 공개되었는지 확인하는 매우 쉽게 찾을. 나는 그런 이유로 귀찮게하지 않으며 더 많은 소음을 추가하고 불필요하게 입력하기 때문에. 또한 공개 구성원을 private또는 로 표시된 구성원과 더 뚜렷하게 만듭니다 protected. 어쨌든, 내 의견 :)
David Sherret

익명 클래스는 어떻습니까? static readonly myReadOnlyProperty클래스 선언시 액세스하는 방법에 대한 아이디어 가 export default class { ... }있습니까? this.myVar, self.myVar, static, default를 시도했습니다 ... 작동하지 않습니다 ... (편집 : default.myVar이 해결책 인 것 같지만 유형 오류가 발생합니다)
Alcalyn

67

상수는 클래스 외부에서 선언하고 클래스 내에서 사용할 수 있습니다. 그렇지 않으면 get속성은 좋은 해결 방법입니다

const MY_CONSTANT: string = "wazzup";

export class MyClass {

    public myFunction() {

        alert(MY_CONSTANT);
    }
}

6
감사; 이식성이 없기 때문에 (모델에서는 상수가 실제로 클래스의 일부가 아니기 때문에)이 구현에 대해 걱정하고 있으며 더 넓은 범위로 정보를 유출하지만 실제 상수라는 이점이 있으므로 알람 벨을 올리지 않고 변경할 수 없습니다.
BeetleJuice

1
본인은 우려 사항을 이해하고 get귀하의 경우 재산 사용이 매우 적절하다고 생각합니다
j3ff

3
angular.io/docs/ts/latest/guide/style-guide.html 하시기 바랍니다 사용 낙타 caase 대신 대문자. 상수는 대문자를 사용하지 않는 것이 좋습니다.
Vadim Kirilchuk

12
각도 스타일 가이드가 아닌 타이프 라이터 스타일 가이드는 ... 질문은 특히 타이프 라이터에 관한 한
VeldMuijz

4
@ Esko 필자는 각 파일이 모듈이기 때문에 typescript에서 const가 파일로 제한된다고 생각합니다. 외부에서 액세스 할 수있게하려면이를 선언 export const한 다음 다른 파일에서 가져와야합니다. 그래도 테스트하기가 쉬울 것입니다. const한 파일에서 a 를 선언하고 내보내거나 가져 오지 않고 다른 파일에서 사용하거나 브라우저 콘솔에서 사용하십시오.
BeetleJuice


11

Angular 2 Opaque Constants라는 매우 멋진 기능을 제공합니다. 불투명 한 상수를 사용하여 클래스를 만들고 모든 상수를 정의하십시오.

import { OpaqueToken } from "@angular/core";

export let APP_CONFIG = new OpaqueToken("my.config");

export interface MyAppConfig {
    apiEndpoint: string;
}

export const AppConfig: MyAppConfig = {    
    apiEndpoint: "http://localhost:8080/api/"    
};

app.module.ts의 공급자에게 주입하십시오.

모든 구성 요소에서 사용할 수 있습니다.

Angular 4 편집 :

Angular 4의 경우 새로운 개념은 주입 토큰 및 불투명 토큰은 Angular 4에서 더 이상 사용되지 않습니다.

주입 토큰 불투명 토큰 위에 기능을 추가하고 TypeScript 제네릭과 주입 토큰을 통해 토큰에 유형 정보를 첨부 할 수 있으며 @Inject를 추가 할 필요가 없습니다.

예제 코드

불투명 토큰을 사용하는 Angular 2

const API_URL = new OpaqueToken('apiUrl'); //no Type Check


providers: [
  {
    provide: DataService,
    useFactory: (http, apiUrl) => {
      // create data service
    },
    deps: [
      Http,
      new Inject(API_URL) //notice the new Inject
    ]
  }
]

인젝션 토큰을 사용하는 Angular 4

const API_URL = new InjectionToken<string>('apiUrl'); // generic defines return value of injector


providers: [
  {
    provide: DataService,
    useFactory: (http, apiUrl) => {
      // create data service
    },
    deps: [
      Http,
      API_URL // no `new Inject()` needed!
    ]
  }
]

주입 토큰은 Opaque 토큰 위에 논리적으로 설계되었으며 Opaque 토큰은 Angular 4에서 더 이상 사용되지 않습니다.


6
하나 추가. 각도는 13 살의 십대처럼 안정적입니다. 릴리스 후 몇 개월 후에 사용되지 않는 기능이 제공됩니다. 자그마한.
Stavm

1
빼기 1 이 질문은 Angular와 아무 관련이 없습니다. TypeScript 솔루션을 요청하고 있습니다.
Ben Nieting

4

readOnly 한정자를 상수와 함께 선언하거나 클래스 외부에서 상수를 선언하고 get 연산자를 사용하여 필요한 클래스에서만 사용하십시오.


1

이를 위해 readonly수정자를 사용할 수 있습니다 . 객체 readonly초기화 중에 만 할당 할 수 있는 객체 속성 .

수업 예 :

class Circle {
  readonly radius: number;

  constructor(radius: number) {
    this.radius = radius;
  }

  get area() {
    return Math.PI * this.radius * 2;
  }
}

const circle = new Circle(12);
circle.radius = 12; // Cannot assign to 'radius' because it is a read-only property.

객체 리터럴의 예 :

type Rectangle = {
  readonly height: number;
  readonly width: number;
};

const square: Rectangle = { height: 1, width: 2 };
square.height = 5 // Cannot assign to 'height' because it is a read-only property

그것은 또한 아는 가치 readonly개질제 순수 타이프 구조체이며, TS는 JS로 컴파일 될 때 구조는 컴파일 JS에 존재하지 않을 것이다. 읽기 전용 인 속성을 수정할 때 TS 컴파일러는 이에 대해 경고합니다 (유효한 JS 임).


-2

나에게 이전의 대답은 없습니다. 정적 클래스를 열거 형으로 변환해야했습니다. 이처럼 :

export enum MyConstants {
  MyFirstConstant = 'MyFirstConstant',
  MySecondConstant = 'MySecondConstant'
}

그런 다음 내 구성 요소에서 다른 답변에서 제안한대로 새 속성을 추가합니다.

export class MyComponent {
public MY_CONTANTS = MyConstans;
constructor() { }
}

그런 다음 컴포넌트의 템플릿에서이 방식으로 사용합니다

<div [myDirective]="MY_CONTANTS.MyFirstConstant"> </div>

편집 : 죄송합니다. 내 문제는 OP와 다릅니다. someelse가 나와 같은 문제가있는 경우에도 여전히 여기에 둡니다.


상수를 저장하기 위해 열거 형을 사용하는 것은 어떤 언어에서도 좋은 습관이 아닙니다.
Sangimed

현재 사용 가능한 솔루션에 가장 적합한 솔루션입니다. 열거 형을 사용하지 않아야하는 방법이지만 Angular를 사용하면 바인딩 가능한 상수를 갖는 가장 깨끗한 방법입니다.
Janne Harju
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.