typescript - declarar - ¿Cómo implementar constantes de clase en mecanografiado?
constantes globales en typescript (6)
En TypeScript, la palabra clave
const
no se puede usar para declarar propiedades de clase.
Al hacerlo, el compilador produce un error con "Un miembro de la clase no puede tener la palabra clave ''const''".
Necesito indicar claramente en el código que una propiedad no debe cambiarse. Quiero que el IDE o el compilador produzcan un error si intento asignar un nuevo valor a la propiedad una vez que se ha declarado. ¿Cómo logran esto?
Actualmente estoy usando una propiedad de solo lectura, pero soy nuevo en Typecript (y JavaScript) y me pregunto si hay una mejor manera:
get MY_CONSTANT():number {return 10};
Estoy usando el mecanografiado 1.8. Sugerencias?
PD: ahora estoy usando el mecanografiado 2.0.3, así que acepté la respuesta de David
Angular 2 proporciona una característica muy agradable llamada como constantes opacas. Cree una clase y defina todas las constantes allí usando constantes opacas.
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/"
};
Inyectarlo en proveedores en app.module.ts
Podrá usarlo en todos los componentes.
EDITAR para Angular 4:
Para Angular 4, el nuevo concepto es Token de inyección y token opaco está en desuso en Angular 4.
El token de inyección agrega funcionalidades sobre tokens opacos, permite adjuntar información de tipo en el token a través de genéricos TypeScript, más tokens de inyección, elimina la necesidad de agregar @Inject
Código de ejemplo
Angular 2 usando tokens opacos
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 usando fichas de inyección
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!
]
}
]
Los tokens de inyección están diseñados lógicamente en la parte superior de los tokens opacos y los tokens opacos están en desuso en Angular 4.
Las constantes pueden declararse fuera de las clases y usarse dentro de su clase.
De lo contrario, la propiedad
get
es una buena solución
const MY_CONSTANT: string = "wazzup";
export class MyClass {
public myFunction() {
alert(MY_CONSTANT);
}
}
Para esto, puede usar el modificador de
readonly
.
Las propiedades de objeto que son de
readonly
solo pueden asignarse durante la inicialización del objeto.
Ejemplo en clases:
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.
Ejemplo en literales de objeto:
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
También vale la pena saber que el modificador de
readonly
es puramente una construcción mecanografiada y cuando el TS se compila a JS, la construcción no estará presente en el JS compilado.
Cuando estamos modificando propiedades que son de solo lectura, el compilador de TS nos advertirá al respecto (es JS válido).
Puede marcar propiedades con un modificador de
readonly
en su declaración:
export class MyClass {
public static readonly MY_PUBLIC_CONSTANT = 10;
private static readonly myPrivateConstant = 5;
}
TypeScript 2.0 tiene el
modificador de
readonly
:
class MyClass {
readonly myReadOnlyProperty = 1;
myMethod() {
console.log(this.myReadOnlyProperty);
this.myReadOnlyProperty = 5; // error, readonly
}
}
new MyClass().myReadOnlyProperty = 5; // error, readonly
No es exactamente una constante porque permite la asignación en el constructor, pero lo más probable es que no sea gran cosa.
Solución alternativa
Una alternativa es usar la palabra clave
static
con
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
Esto tiene el beneficio de no ser asignable en el constructor y solo existir en un lugar.
Utilice el modificador readOnly con la constante que necesita declarar o puede declarar una constante fuera de la clase y úsela específicamente solo en la clase requerida utilizando el operador get.