TypeScript 中的公共静态常量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22991968/
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
public static const in TypeScript
提问by Crystal
Is there such a thing as public static constants in TypeScript? I have a class that looks like:
TypeScript 中是否有公共静态常量之类的东西?我有一个看起来像的类:
export class Library {
public static BOOK_SHELF_NONE: string = "None";
public static BOOK_SHELF_FULL: string = "Full";
}
In that class, I can do Library.BOOK_SHELF_NONE
and the tsc doesn't complain. But if I try to use the class Library elsewhere, and try to do the same thing, it doesn't recognize it.
在那堂课上,我可以做到Library.BOOK_SHELF_NONE
,tsc 也不会抱怨。但是如果我尝试在其他地方使用类库,并尝试做同样的事情,它就无法识别它。
采纳答案by raina77ow
Here's what's this TS snippet compiled into (via TS Playground):
这是编译成的 TS 片段(通过TS Playground):
define(["require", "exports"], function(require, exports) {
var Library = (function () {
function Library() {
}
Library.BOOK_SHELF_NONE = "None";
Library.BOOK_SHELF_FULL = "Full";
return Library;
})();
exports.Library = Library;
});
As you see, both properties defined as public static
are simply attached to the exported function (as its properties); therefore they should be accessible as long as you properly access the function itself.
如您所见,定义为 的两个属性public static
都简单地附加到导出的函数(作为其属性);因此,只要您正确访问功能本身,它们就应该可以访问。
回答by WiredPrairie
If you did want something that behaved more like a static constant value in modern browsers (in that it can't be changed by other code), you could add a get
only accessor to the Library
class (this will only work for ES5+ browsers and NodeJS):
如果你确实想要一些在现代浏览器中表现得更像静态常量值的东西(因为它不能被其他代码改变),你可以get
向Library
类添加一个唯一的访问器(这只适用于 ES5+ 浏览器和 NodeJS) :
export class Library {
public static get BOOK_SHELF_NONE():string { return "None"; }
public static get BOOK_SHELF_FULL():string { return "Full"; }
}
var x = Library.BOOK_SHELF_NONE;
console.log(x);
Library.BOOK_SHELF_NONE = "Not Full";
x = Library.BOOK_SHELF_NONE;
console.log(x);
If you run it, you'll see how the attempt to set the BOOK_SHELF_NONE
property to a new value doesn't work.
如果您运行它,您将看到如何将BOOK_SHELF_NONE
属性设置为新值的尝试不起作用。
2.0
2.0
In TypeScript 2.0, you can use readonly
to achieve very similar results:
在 TypeScript 2.0 中,您可以使用readonly
来实现非常相似的结果:
export class Library {
public static readonly BOOK_SHELF_NONE = "None";
public static readonly BOOK_SHELF_FULL = "Full";
}
The syntax is a bit simpler and more obvious. However, the compiler prevents changes rather than the run time (unlike in the first example, where the change would not be allowed at all as demonstrated).
语法更简单,更明显。但是,编译器会阻止更改而不是运行时(与第一个示例不同,在第一个示例中,如演示的那样根本不允许更改)。
回答by Ivan Castellanos
You can do it using namespaces, like this:
您可以使用namespaces来做到这一点,如下所示:
export namespace Library {
export const BOOK_SHELF_NONE: string = 'NONE';
}
Then you can import it from anywhere else:
然后你可以从其他任何地方导入它:
import {Library} from './Library';
console.log(Library.BOOK_SHELF_NONE);
If you need a class there as well include it inside the namespace: export class Book {...}
如果你需要一个类,也可以将它包含在命名空间中: export class Book {...}
回答by olsn
Meanwhile this can be solved through a decorator in combination with Object.freeze
or Object.defineProperty
, I'm using this, it's a little bit prettier than using tons of getters. You can copy/paste this directly TS Playgroundto see it in action. - There are two options
同时,这可以通过装饰器与Object.freeze
or结合来解决Object.defineProperty
,我正在使用它,它比使用大量的吸气剂要漂亮一点。您可以直接复制/粘贴此TS Playground以查看其实际效果。- 有两种选择
Make individual fields "final"
使单个字段“最终”
The following decorator converts both, annotated static and non-static fields to "getter-only-properties".
以下装饰器将带注释的静态和非静态字段都转换为“getter-only-properties”。
Note: If an instance-variable with no initial value is annotated @final
, then the first assigned value (no matter when) will be the final one.
注意:如果一个没有初始值的实例变量被注解@final
,那么第一个赋值(无论何时)将是最后一个。
// example
class MyClass {
@final
public finalProp: string = "You shall not change me!";
@final
public static FINAL_FIELD: number = 75;
public static NON_FINAL: string = "I am not final."
}
var myInstance: MyClass = new MyClass();
myInstance.finalProp = "Was I changed?";
MyClass.FINAL_FIELD = 123;
MyClass.NON_FINAL = "I was changed.";
console.log(myInstance.finalProp); // => You shall not change me!
console.log(MyClass.FINAL_FIELD); // => 75
console.log(MyClass.NON_FINAL); // => I was changed.
The Decorator: Make sure you include this in your code!
装饰者:确保将其包含在您的代码中!
/**
* Turns static and non-static fields into getter-only, and therefor renders them "final".
* To use simply annotate the static or non-static field with: @final
*/
function final(target: any, propertyKey: string) {
const value: any = target[propertyKey];
// if it currently has no value, then wait for the first setter-call
// usually the case with non-static fields
if (!value) {
Object.defineProperty(target, propertyKey, {
set: function (value: any) {
Object.defineProperty(this, propertyKey, {
get: function () {
return value;
},
enumerable: true,
configurable: false
});
},
enumerable: true,
configurable: true
});
} else { // else, set it immediatly
Object.defineProperty(target, propertyKey, {
get: function () {
return value;
},
enumerable: true
});
}
}
As an alternative to the decorator above, there would also be a strict version of this, which would even throw an Error when someone tried to assign some value to the field with "use strict";
being set. (This is only the static part though)
作为上述装饰器的替代方案,还有一个严格的版本,当有人试图为"use strict";
设置的字段分配一些值时,它甚至会抛出错误。(虽然这只是静态部分)
/**
* Turns static fields into getter-only, and therefor renders them "final".
* Also throws an error in strict mode if the value is tried to be touched.
* To use simply annotate the static field with: @strictFinal
*/
function strictFinal(target: any, propertyKey: string) {
Object.defineProperty(target, propertyKey, {
value: target[propertyKey],
writable: false,
enumerable: true
});
}
Make every static field "final"
使每个静态字段“最终”
Possible Downside: This will only work for ALL statics of that class or for none, but cannot be applied to specific statics.
可能的缺点:这仅适用于该类的所有静态或不适用,但不能应用于特定的静态。
/**
* Freezes the annotated class, making every static 'final'.
* Usage:
* @StaticsFinal
* class MyClass {
* public static SOME_STATIC: string = "SOME_STATIC";
* //...
* }
*/
function StaticsFinal(target: any) {
Object.freeze(target);
}
// Usage here
@StaticsFinal
class FreezeMe {
public static FROZEN_STATIC: string = "I am frozen";
}
class EditMyStuff {
public static NON_FROZEN_STATIC: string = "I am frozen";
}
// Test here
FreezeMe.FROZEN_STATIC = "I am not frozen.";
EditMyStuff.NON_FROZEN_STATIC = "I am not frozen.";
console.log(FreezeMe.FROZEN_STATIC); // => "I am frozen."
console.log(EditMyStuff.NON_FROZEN_STATIC); // => "I am not frozen."
回答by Andrew
Thank you WiredPrairie!
感谢有线草原!
Just to expand on your answer a bit, here is a complete example of defining a constants class.
只是为了扩展您的答案,这里是定义常量类的完整示例。
// CYConstants.ts
class CYConstants {
public static get NOT_FOUND(): number { return -1; }
public static get EMPTY_STRING(): string { return ""; }
}
export = CYConstants;
To use
使用
// main.ts
import CYConstants = require("./CYConstants");
console.log(CYConstants.NOT_FOUND); // Prints -1
console.log(CYConstants.EMPTY_STRING); // Prints "" (Nothing!)
回答by Andrew
The following solution also works as of TS 1.7.5.
以下解决方案也适用于 TS 1.7.5。
// Constancts.ts
export const kNotFoundInArray = -1;
export const AppConnectionError = new Error("The application was unable to connect!");
export const ReallySafeExtensions = ["exe", "virus", "1337h4x"];
To use:
使用:
// Main.ts
import {ReallySafeExtensions, kNotFoundInArray} from "./Constants";
if (ReallySafeExtensions.indexOf("png") === kNotFoundInArray) {
console.log("PNG's are really unsafe!!!");
}
回答by silvanasono
You can use a getter, so that your property is going to be reading only. Example:
您可以使用 getter,这样您的属性将是只读的。例子:
export class MyClass {
private _LEVELS = {
level1: "level1",
level2: "level2",
level2: "level2"
};
public get STATUSES() {
return this._LEVELS;
}
}
Used in another class:
在另一个类中使用:
import { MyClass } from "myclasspath";
class AnotherClass {
private myClass = new MyClass();
tryLevel() {
console.log(this.myClass.STATUSES.level1);
}
}
回答by normalUser
Just simply 'export' variable and 'import' in your class
只需在您的班级中简单地“导出”变量和“导入”
export var GOOGLE_API_URL = 'https://www.googleapis.com/admin/directory/v1';
// default err string message
export var errStringMsg = 'Something went wrong';
Now use it as,
现在用它作为,
import appConstants = require('../core/AppSettings');
console.log(appConstants.errStringMsg);
console.log(appConstants.GOOGLE_API_URL);