Vyhledávání na webu

typescript - Jak implementovat konstanty třídy?


V TypeScriptu nelze použít klíčové slovo const k deklaraci vlastností třídy. Pokud se to zkusí, kompilátor způsobí chybu s hlášením „Člen třídy nemůže mít klíčové slovo 'const'."

Zjistil jsem, že potřebuji jasně v kódu naznačit, že vlastnost by neměla být měněna. Chci, aby IDE nebo kompilátor hlásil chybu, pokud se pokusím přiřadit nové hodnoty vlastnosti poté, co byla deklarována. Jak to u vás dosahujete?

Momentálně používám vlastnost jen pro čtení, ale zajímalo by mě, jestli existuje lepší způsob:

get MY_CONSTANT():number {return 10};

Používám TypeScript 1.8. Máte nějaké návrhy?

PS: Teď používám TypeScript 2.0.3, takže jsem přijal Davidovu odpověď

Odpověď č. 1

TypeScript 2.0 má modifikátor readonly:

class MyClass {
    readonly myReadOnlyProperty = 1;

    myMethod() {
        console.log(this.myReadOnlyProperty);
        this.myReadOnlyProperty = 5; // error, readonly
    }
}

new MyClass().myReadOnlyProperty = 5; // error, readonly

Není to přesně konstanta, protože umožňuje přiřazení v konstruktoru, ale to pravděpodobně není velký problém.

Alternativní řešení

Alternativou je použití klíčového slova static spolu s 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

To má tu výhodu, že to nelze přiřadit v konstruktoru a existuje to pouze na jednom místě.

Odpověď č. 2

Konstanty mohou být deklarovány mimo třídy a použity ve vaší třídě. Jinak je vlastnost get hezkým řešením.

const MY_CONSTANT: string = "wazzup";

export class MyClass {

    public myFunction() {

        alert(MY_CONSTANT);
    }
}

Odpověď č. 3

Můžete označit vlastnosti pomocí modifikátoru readonly ve vašem deklaraci:

export class MyClass {
  public static readonly MY_PUBLIC_CONSTANT = 10;
  private static readonly myPrivateConstant = 5;
}

@viz kniha TypeScript Deep Dive - Readonly

Odpověď č. 4

Angular 2 poskytuje velmi pěknou funkci nazývanou Opaque Constants. Vytvořte třídu a definujte všechny konstanty tam pomocí opaque constants.

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/"    
};

Injektujte to do poskytovatelů v app.module.ts

Budete jej moci používat napříč všemi komponentami.

ÚPRAVA pro Angular 4 :

Pro Angular 4 je novým konceptem Injection Token a Opaque token je v Angular 4 zastaralý.

Injekční token přidává funkce nad Opaque Tokens, umožňuje připojit informace o typu k tokenu pomocí generik TypeScriptu, navíc Injekční tokeny odstraňují potřebu přidávat @Inject

Ukázkový kód

Angular 2 Používání neprůhledných tokenů

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 Použití injekčních tokenů

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!
    ]
  }
]

Injekční tokeny jsou logicky navrženy nad nezřetelnými tokeny a nezřetelné tokeny jsou v Angular 4 zastaralé.

Odpověď č. 5

Všechny odpovědi s readonly jsou vhodné pouze v čistém prostředí TS - pokud by se z toho někdy měla vytvořit knihovna, pak to ve skutečnosti nic nebrání, jen to poskytuje varování pro samotný TS kompilátor.

Statické také není správné - to znamená přidání metody do třídy, ne do instance třídy - takže je třeba se k tomu přímo přistoupit.

Existuje několik způsobů, jak to řešit, ale čistě v TypeScriptu je způsobem použití getteru - přesně tak, jak jste už udělali.

Alternativní způsob je nastavit ho jako readonly, ale pak použít Object.defineProperty k jeho uzamčení - to je téměř to samé, co se děje přes getter, ale můžete ho uzamknout, aby měl hodnotu, spíše než metodu, kterou použijete k jejímu získání -

class MyClass {
    MY_CONSTANT = 10;

    constructor() {
        Object.defineProperty(this, "MY_CONSTANT", {value: this.MY_CONSTANT});
    }
}

Výchozí nastavení jej činí pouze pro čtení, ale podívejte se do dokumentace pro více informací.

Související články