Как реализовать кластерные константы в typescript?
В TypeScript ключевое слово const
нельзя использовать для объявления свойств класса. Это приводит к ошибке компилятора: "Член класса не может иметь ключевое слово" const "."
Мне нужно четко указать в коде, что свойство не должно быть изменено. Я хочу, чтобы среда IDE или компилятор выдавали ошибку, если я пытаюсь присвоить новое значение свойству после его объявления. Как вы, ребята, добились этого?
В настоящее время я использую свойство только для чтения, но я новичок в Typescript (и JavaScript) и задаюсь вопросом, есть ли лучший способ:
get MY_CONSTANT():number {return 10};
Я использую машинопись 1.8. Предложения?
PS: сейчас я использую машинопись 2.0.3, поэтому я принял ответ Дэвида
Ответы
Ответ 1
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
Преимущество этого состоит в том, что он не может быть назначен в конструкторе и существует только в одном месте.
Ответ 2
Константы могут быть объявлены вне классов и использоваться в вашем классе. В противном случае свойство get
является хорошим обходным способом
const MY_CONSTANT: string = "wazzup";
export class MyClass {
public myFunction() {
alert(MY_CONSTANT);
}
}
Ответ 3
Вы можете пометить свойства модификатором readonly
в своем объявлении:
export class MyClass {
public static readonly MY_PUBLIC_CONSTANT = 10;
private static readonly myPrivateConstant = 5;
}
@См. TypeScript Deep Dive book - только для чтения
Ответ 4
Angular 2 Обеспечивает очень приятную функцию, называемую непрозрачными константами.
Создайте класс и определите все константы там, используя непрозрачные константы.
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
Вы сможете использовать его для всех компонентов.
EDIT для Angular 4:
Для Angular 4 новая концепция - токен впрыска, а непрозрачный токен устарел в Angular 4.
Инъекционный токен Добавляет функциональные возможности поверх непрозрачных токенов, он позволяет привязывать информацию о типе к токену с помощью TypeScript generics, а также токенов Injection, устраняет необходимость добавления @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!
]
}
]
Инекеры для инъекций спроектированы логически поверх непрозрачных жетонов, а непрозрачные жетоны устарели в Angular 4.
Ответ 5
Используйте модификатор readOnly с константой, которую нужно объявить, или можно объявить константу вне класса и использовать ее специально только в требуемом классе, используя оператор get.
Ответ 6
Для этого вы можете использовать модификатор 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).