variable type objetos number listas initialize clases array typescript

objetos - typescript type of variable



Const estático público en TypeScript (8)

¿Hay algo así como constantes estáticas públicas en TypeScript? Tengo una clase que se parece a:

export class Library { public static BOOK_SHELF_NONE: string = "None"; public static BOOK_SHELF_FULL: string = "Full"; }

En esa clase, puedo hacer Library.BOOK_SHELF_NONE y el tsc no se queja. Pero si trato de utilizar la biblioteca de la clase en otro lugar, y trato de hacer lo mismo, no lo reconoce.


¡Gracias WiredPrairie!

Solo para ampliar un poco tu respuesta, aquí hay un ejemplo completo de definición de una clase de constantes.

// CYConstants.ts class CYConstants { public static get NOT_FOUND(): number { return -1; } public static get EMPTY_STRING(): string { return ""; } } export = CYConstants;

Usar

// main.ts import CYConstants = require("./CYConstants"); console.log(CYConstants.NOT_FOUND); // Prints -1 console.log(CYConstants.EMPTY_STRING); // Prints "" (Nothing!)


Esto es lo que se compila en este fragmento de TS (a través de 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; });

Como puede ver, ambas propiedades definidas como public static simplemente se adjuntan a la función exportada (como sus propiedades); por lo tanto, deben ser accesibles siempre que acceda correctamente a la función en sí.


La siguiente solución también funciona a partir de 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"];

Usar:

// Main.ts import {ReallySafeExtensions, kNotFoundInArray} from "./Constants"; if (ReallySafeExtensions.indexOf("png") === kNotFoundInArray) { console.log("PNG''s are really unsafe!!!"); }


Mientras tanto, esto se puede resolver a través de un decorador en combinación con Object.freeze u Object.defineProperty , estoy usando esto, es un poco más bonito que usar toneladas de getters. Puede copiar / pegar directamente TS Playground para verlo en acción. - Hay dos opciones

Hacer que los campos individuales sean "finales"

El siguiente decorador convierte los campos anotados y no estáticos anotados en "propiedades solo-getter".

Nota : Si una variable de instancia sin valor inicial se anota @final , entonces el primer valor asignado (no importa cuándo) será el último.

// 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: ¡Asegúrate de incluir esto en tu código!

/** * 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 }); } }

Como alternativa al decorador anterior, también habría una versión estricta de esto, que incluso arrojaría un error cuando alguien intentara asignar algún valor al campo con "use strict"; siendo establecido. (Esta es solo la parte estática)

/** * 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 }); }

Hacer que cada campo estático sea "final"

Posible inconveniente: Esto solo funcionará para TODAS las estáticas de esa clase o para ninguna, pero no se puede aplicar a estáticas específicas.

/** * 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."


Puede usar un getter para que su propiedad solo sea de lectura. Ejemplo:

export class MyClass { private _LEVELS = { level1: "level1", level2: "level2", level2: "level2" }; public get STATUSES() { return this._LEVELS; } }

Usado en otra clase:

import { MyClass } from "myclasspath"; class AnotherClass { private myClass = new MyClass(); tryLevel() { console.log(this.myClass.STATUSES.level1); } }


Puedes hacerlo usando namespaces , como este:

export namespace Library { export const BOOK_SHELF_NONE: string = ''NONE''; }

Luego puede importarlo desde cualquier otro lugar:

import {Library} from ''./Library''; console.log(Library.BOOK_SHELF_NONE);

Si necesita una clase allí, inclúyalo dentro del espacio de nombres: export class Book {...}


Si quería algo que se comportara más como un valor de constante estático en los navegadores modernos (en el sentido de que no puede ser modificado por otro código), podría agregar un acceso exclusivo a la clase Library (esto solo funcionará para los navegadores ES5 + y 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);

Si lo ejecuta, verá cómo no funciona el intento de establecer la propiedad BOOK_SHELF_NONE en un nuevo valor.

2.0

En TypeScript 2.0, puede usar readonly para obtener resultados muy similares:

export class Library { public static readonly BOOK_SHELF_NONE = "None"; public static readonly BOOK_SHELF_FULL = "Full"; }

La sintaxis es un poco más simple y más obvia. Sin embargo, el compilador evita los cambios en lugar del tiempo de ejecución (a diferencia del primer ejemplo, donde el cambio no se permitiría en absoluto como se demostró).


Simplemente ''exportar'' variable e ''importar'' en su clase

export var GOOGLE_API_URL = ''https://www.googleapis.com/admin/directory/v1''; // default err string message export var errStringMsg = ''Something went wrong'';

Ahora úsalo como,

import appConstants = require(''../core/AppSettings''); console.log(appConstants.errStringMsg); console.log(appConstants.GOOGLE_API_URL);