typescript 如何在打字稿中实现类常量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37265275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to implement class constants in typescript?
提问by BeetleJuice
In TypeScript, the const
keyword cannot be used to declare class properties. Doing so causes the compiler to an error with "A class member cannot have the 'const' keyword."
在 TypeScript 中,const
关键字不能用于声明类属性。这样做会导致编译器出现“类成员不能有 'const' 关键字”的错误。
I find myself in need to clearly indicate in code that a property should not be changed. I want the IDE or compiler to error if I attempt to assign a new value to the property once it has been declared. How do you guys achieve this?
我发现自己需要在代码中明确指出不应更改属性。如果在声明属性后尝试为其分配新值,我希望 IDE 或编译器出错。你们是如何做到这一点的?
I'm currently using a read-only property, but I'm new to Typescript (and JavaScript) and wonder whether there is a better way:
我目前使用的是只读属性,但我是 Typescript(和 JavaScript)的新手,想知道是否有更好的方法:
get MY_CONSTANT():number {return 10};
I'm using typescript 1.8. Suggestions?
我正在使用打字稿 1.8。建议?
PS: I'm now using typescript 2.0.3, so I've accepted David's answer
PS:我现在使用的是 typescript 2.0.3,所以我接受了David 的回答
回答by David Sherret
TypeScript 2.0 has the readonly
modifier:
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
It's not exactly a constant because it allows assignment in the constructor, but that's most likely not a big deal.
它不完全是一个常量,因为它允许在构造函数中赋值,但这很可能没什么大不了的。
Alternative Solution
替代方案
An alternative is to use the static
keyword with readonly
:
另一种方法是使用static
关键字 with 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
This has the benefit of not being assignable in the constructor and only existing in one place.
这样做的好处是不能在构造函数中赋值,而只能存在于一处。
回答by j3ff
Constants can be declare outside of classes and use within your class. Otherwise the get
property is a nice workaround
常量可以在类之外声明并在您的类中使用。否则,该get
属性是一个不错的解决方法
const MY_CONSTANT: string = "wazzup";
export class MyClass {
public myFunction() {
alert(MY_CONSTANT);
}
}
回答by am0wa
You can mark properties with readonly
modifier in your declaration:
您可以readonly
在声明中使用修饰符标记属性:
export class MyClass {
public static readonly MY_PUBLIC_CONSTANT = 10;
private static readonly myPrivateConstant = 5;
}
回答by Parth Ghiya
Angular 2 Provides a very nice feature called as Opaque Constants. Create a class & Define all the constants there using opaque constants.
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/"
};
Inject it in providers in app.module.ts
将其注入 app.module.ts 中的提供程序中
You will be able to use it across every components.
您将能够在每个组件中使用它。
EDIT for Angular 4 :
为 Angular 4 编辑:
For Angular 4 the new concept is Injection Token & Opaque token is Deprecated in Angular 4.
对于 Angular 4,新概念是注入令牌和不透明令牌在 Angular 4 中已弃用。
Injection Token Adds functionalities on top of Opaque Tokens, it allows to attach type info on the token via TypeScript generics, plus Injection tokens, removes the need of adding @Inject
注入令牌在不透明令牌之上添加功能,它允许通过 TypeScript 泛型在令牌上附加类型信息,加上注入令牌,消除了添加 @Inject 的需要
Example Code
示例代码
Angular 2 Using Opaque Tokens
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 Using Injection Tokens
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!
]
}
]
Injection tokens are designed logically on top of Opaque tokens & Opaque tokens are deprecated in Angular 4.
注入令牌是在 Opaque 令牌之上逻辑设计的,而 Opaque 令牌在 Angular 4 中已弃用。
回答by Krishna Ganeriwal
Either use readOnly modifier with the constant one needs to declare or one might declare a constant outside the class and use it specifically only in the required class using get operator.
要么将 readOnly 修饰符与需要声明的常量一起使用,要么可以在类之外声明一个常量,并使用 get 运算符专门仅在所需的类中使用它。
回答by Willem van der Veen
For this you can use the readonly
modifier. Object properties which are readonly
can only be assigned during initialization of the object.
为此,您可以使用readonly
修饰符。这是对象属性readonly
只能在对象初始化时被分配。
Example in classes:
类中的示例:
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.
Example in Object literals:
对象文字中的示例:
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
It's also worth knowing that the readonly
modifier is purely a typescript construct and when the TS is compiled to JS the construct will not be present in the compiled JS. When we are modifying properties which are readonly the TS compiler will warn us about it (it is valid JS).
还值得知道的是,readonly
修饰符纯粹是一个打字稿构造,当 TS 被编译为 JS 时,该构造将不会出现在已编译的 JS 中。当我们修改只读属性时,TS 编译器会警告我们(它是有效的 JS)。
回答by Janne Harju
For me none of earlier answer works. I did need to convert my static class to enum. Like this:
对我来说,早期的答案都不起作用。我确实需要将我的静态类转换为枚举。像这样:
export enum MyConstants {
MyFirstConstant = 'MyFirstConstant',
MySecondConstant = 'MySecondConstant'
}
Then in my component I add new property as suggested in other answers
然后在我的组件中,我按照其他答案中的建议添加了新属性
export class MyComponent {
public MY_CONTANTS = MyConstans;
constructor() { }
}
Then in my component's template I use it this way
然后在我的组件模板中,我以这种方式使用它
<div [myDirective]="MY_CONTANTS.MyFirstConstant"> </div>
EDIT: Sorry. My problem was different than OP's. I still leave this here if someelse have same problem than I.
编辑:对不起。我的问题与 OP 不同。如果有人和我有同样的问题,我仍然把它留在这里。