網站搜尋

在 Angular 中使用 Typescript 的常數變數與枚舉類型比較


在為 TypeScript Angular 元件宣告常數變數時,最佳做法是什麼?

我已經使用了這兩種方法,但我想知道哪一個比較好。

第一種方法,是在類別之前或在獨立的 TypeScript 文件中以大寫字母宣告全域常數變數。然而,當我在類別元件中有好幾個這樣的大寫全域常數變數時,我並不太喜歡這樣做。

const STAGE_1: string = 'stage1';

STAGE_1

第二種方法,是在 TypeScript 文件中創建一個枚舉,然後將其導入到組件中。

export enum Stage {
  Stage1 = 'stage1',
}

Stage.Stage1

我最近一直在使用第二種方法,因為我在 TypeScript 手冊中看到了它。然而,我在其他語言如 Java 和 Go 中看到了第一種方法。

有任何建議或補充嗎?

答案#1

實際上有三種不同的方法:

類型

允許您指定一種類型,該類型僅限於給定的值。由於它們不會生成任何代碼,因此它們在編譯時就像枚舉,但在運行時不存在。當處理返回預定義值的 REST API 時,它們非常有用;例如:

type Stage = "stage1" | "stage2";

function fnByType(value: Stage) {
}

fnByType("stage1"); // OK
fnByType("stage2"); // OK
fnByType("stage3"); // Not assignable!

列舉

允許您指定一個僅限於給定值的枚舉。它們確實會生成代碼,因此在編譯時和運行時都存在。因為它們在運行時存在,您可以列舉它們所有的鍵和值;例如:

enum Stage {
    Stage1 = "stage1",
    Stage2 = "stage2"
}

function fnByEnum(value: Stage) {
}

fnByEnum(Stage.Stage1); // OK
fnByEnum(Stage.Stage2); // OK
fnByEnum("stage1") // Not assignable!
fnByEnum("stage3") // Not assignable!

console.log(Object.keys(Stage)); // ["Stage1", "Stage2"]
console.log(Object.values(Stage)); // ["stage1", "stage2"] 

常數

允許你定義一個新的常數(唯讀)變數。當你想避免使用所謂的「魔法值」(其意圖對讀者來說基本上是未知的,但在你的程式中有特定意義的值)時,這會非常有用,這意味著你可以更好地解釋你的程式在做什麼。此外,它支持 DRY(不要重複自己)原則,因為你可以引用常數的值,而不是在程式中重複使用「魔法值」。最後,這也意味著如果你需要更新常數的值,你不需要在程式中搜尋所有該值的使用位置;你只需更新一次,例如:

const STAGE1: string = "stage1";
const STAGE2: string = "stage2";

function fnByString(value: string) {
}

fnByString(STAGE1); // OK
fnByString(STAGE2); // OK
fnByString("stage3"); // OK...but re-read the benefits of NOT using "magic values"

你可以將這三個概念互換使用,並互相補充;例如:

type Stage = "stage1" | "stage2";

const STAGE1: string = "stage1";
const STAGE2: string = "stage2";

function fnByType(value: Stage) {
}

fnByType(STAGE1); // OK
fnByType(STAGE2); // OK
fnByType("stage3"); // Not assignable!

最後,給你一些思考的素材。如果你能先定義 const 值,然後用它們來定義一種類型的預設值會很好,但據我所見,下面的做法目前還不可能:

const STAGE1: string = "stage1";
const STAGE2: string = "stage2";

type Stage = STAGE1 | STAGE2;

function fnByType(value: Stage) {
}

fnByType(STAGE1); // OK
fnByType(STAGE2); // OK
fnByType("stage3"); // Not assignable!

答案#2

將類型和枚舉一起使用

你好,這篇文章只是為了強調在 typescript 中使用 types 和 enums 的更實用技巧

class __EntityNames {
  readonly User = 'User';
  readonly Role = 'Role';
  readonly Permission = 'Permission';

  private constructor() {
    // Private constructor
  }

  static instance() {
    return new __EntityNames();
  }
}


/**
 * EntityNames as enum
 */
export const EntityNames = __EntityNames.get();



/**
 * EntityNames as type
 */
export type EntityName = keyof __EntityNames;


讓我們在程式碼中使用它

/**
 * Shows type error! And supports autocomplete
 */
const value: EntityName = 'Action';

const enumValue:EntityNames = EntityNames.User