TypeScript中的public static const
在TypeScript中是否存在公共静态常量? 我有一个类,看起来像:
export class Library { public static BOOK_SHELF_NONE: string = "None"; public static BOOK_SHELF_FULL: string = "Full"; }  在那个课上,我可以做Library.BOOK_SHELF_NONE和tsc不会抱怨。 但是,如果我尝试在其他地方使用类库,并尝试做同样的事情,它不认识它。 
这是什么TS代码片段编译成(通过TS游乐场 ):
 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; }); 
 正如你看到的,这两个定义为public static属性只是附加到导出的函数(作为它的属性)。 因此,只要您正确访问函数本身,就应该可以访问它们。 
 如果你确实想要在现代浏览器中performance得更像是一个静态的常量值(因为它不能被其他代码所改变),你可以在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); 
 如果您运行它,您将看到如何尝试将BOOK_SHELF_NONE属性设置为新值不起作用。 
2.0
 在TypeScript 2.0中,你可以使用readonly来获得非常相似的结果: 
 export class Library { public static readonly BOOK_SHELF_NONE = "None"; public static readonly BOOK_SHELF_FULL = "Full"; } 
语法有点简单和明显。 但是,编译器可以防止更改,而不是运行时间(不像第一个示例中那样,根本不允许更改)。
你可以使用命名空间来做到这一点:
 export namespace Library { export const BOOK_SHELF_NONE: string = 'NONE'; } 
那么你可以从其他地方导入它:
 import {Library} from './Library'; console.log(Library.BOOK_SHELF_NONE); 
 如果您需要一个类,并将其包含在命名空间中: export class Book {...} 
 同时这可以通过装饰器与Object.freeze或Object.defineProperty结合来解决,我使用这个,比使用大量的getter稍微漂亮些。 您可以直接复制/粘贴到TS Playground,以便看到它在行动。  – 有两个选项 
使个别领域“最终”
下面的装饰器将注释的静态和非静态字段都转换为“getter-only-properties”。
  注意 :如果没有初始值的实例variables被@final为@final ,那么第一个赋值(不pipe何时)将是最后一个。 
 // 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. 
装饰者:确保你包含在你的代码!
 /** * 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 }); } } 
 作为上面装饰器的替代scheme,还会有一个严格的版本,当有人试图用"use strict";来赋值字段时,甚至会抛出一个错误"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 }); } 
使每个静态字段“最终”
可能的下行:这将只适用于该类的所有静态或无效,但不能应用于特定的静态。
 /** * 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." 
谢谢你WiredPrairie!
稍微扩展一下你的答案,下面是一个定义常量类的完整例子。
 // CYConstants.ts class CYConstants { public static get NOT_FOUND(): number { return -1; } public static get EMPTY_STRING(): string { return ""; } } export = CYConstants; 
使用
 // main.ts import CYConstants = require("./CYConstants"); console.log(CYConstants.NOT_FOUND); // Prints -1 console.log(CYConstants.EMPTY_STRING); // Prints "" (Nothing!) 
以下解决scheme也适用于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"]; 
使用:
 // Main.ts import {ReallySafeExtensions, kNotFoundInArray} from "./Constants"; if (ReallySafeExtensions.indexOf("png") === kNotFoundInArray) { console.log("PNG's are really unsafe!!!"); } 
只需简单地在你的课堂上“导出”variables和“导入”即可
 export var GOOGLE_API_URL = 'https://www.googleapis.com/admin/directory/v1'; // default err string message export var errStringMsg = 'Something went wrong'; 
现在使用它,
 import appConstants = require('../core/AppSettings'); console.log(appConstants.errStringMsg); console.log(appConstants.GOOGLE_API_URL); 
你可以使用吸气剂,这样你的财产将只能读取。 例:
 export class MyClass { private _LEVELS = { level1: "level1", level2: "level2", level2: "level2" }; public get STATUSES() { return this._LEVELS; } } 
用于另一个类:
 import { MyClass } from "myclasspath"; class AnotherClass { private myClass = new MyClass(); tryLevel() { console.log(this.myClass.STATUSES.level1); } }