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.