web-dev-qa-db-ja.com

TypeScript:関数を列挙に追加

TypeScriptのEnum型に関数を追加することは可能ですか?

例えば:

_enum Mode {
    landscape,
    portrait,

    // the dream...
    toString() { console.log(this); } 
}
_

または:

_class ModeExtension {
    public toString = () => console.log(this);
}

enum Mode extends ModeExtension {
    landscape,
    portrait,
}
_

もちろん、toString()関数にはswitchのようなものが含まれますが、ユースケースは次の行に沿って流れます。

_class Device {
    constructor(public mode:Mode) {
        console.log(this.mode.toString());
    }
}
_

enumを拡張するのがなぜ奇妙なことになるのか理解できますが、それが可能かどうか疑問に思っています。

49
Mr. Baudin

Enumとは別のクラスを用意して、それを使用して必要なものを取得するか、ネームスペースをEnumにマージして、同じ場所に見えるものすべてを取得することができます。

モードユーティリティクラス

したがって、これはまさにあなたが望んでいることではありませんが、これにより、静的メソッドを使用して「Mode to string」動作をカプセル化できます。

class ModeUtil {
    public static toString(mode: Mode) {
        return Mode[mode];
    }
}

次のように使用できます。

const mode = Mode.portrait;
const x = ModeUtil.toString(mode);
console.log(x);

モード列挙/名前空間マージ

追加のメソッドでEnumのように見えるものを作成するために、名前空間をEnumにマージできます。

enum Mode {
    X,
    Y
}

namespace Mode {
    export function toString(mode: Mode): string {
        return Mode[mode];
    }

    export function parse(mode: string): Mode {
        return Mode[mode];
    }
}

const mode = Mode.X;

const str = Mode.toString(mode);
alert(str);

const m = Mode.parse(str);
alert(m);
65
Fenton

角括弧を使用して、非const列挙型の文字列値を取得できます。

class Device {
    constructor(public mode:Mode) {
        console.log(Mode[this.mode]);
    }
}

また、いくつかの列挙固有のutil関数を列挙に入れることもできますが、これは静的なクラスメンバーのようなものです。

enum Mode {
    landscape,
    portrait
}

namespace Mode {
    export function doSomething(mode:Mode) {
        // your code here
    }
}
27
Benjamin

enumを列挙パターンに変換します。それ以外の場合はタイプのカプセル化オプションを制限するため、これは多くの言語で一般的に優れたプラクティスであると思います。特定の列挙値に依存するデータまたは機能が実際に列挙の各インスタンスにのみ入る必要がある場合、列挙値でswitchになる傾向があります。デモンストレーションするコードをいくつか追加しました。

基になる列挙値に特に依存している場合、これは機能しない可能性があります。その場合、古い値のメンバーを追加し、新しいプロパティを使用するために必要な場所を変換する必要があります。

class Mode {
   public static landscape = new Mode(1920, 1080);
   public static portrait = new Mode(1080, 1920);

   public get Width(): number { return this.mWidth; }
   public get Height(): number { return this.mHeight; }

   // private constructor if possible in a future version of TS
   constructor(
      private mWidth: number,
      private mHeight: number
   ) {
   }

   public GetAspectRatio() {
      return this.mWidth / this.mHeight;
   }
}
5
Dave Cousineau

プライベートコンストラクターやstatic get returnオブジェクトのように列挙型を作成できます

export class HomeSlideEnum{

  public static get friendList(): HomeSlideEnum {

    return new HomeSlideEnum(0, "friendList");

  }
  public static getByOrdinal(ordinal){
    switch(ordinal){
      case 0:

        return HomeSlideEnum.friendList;
    }
  }

  public ordinal:number;
  public key:string;
  private constructor(ordinal, key){

    this.ordinal = ordinal;
    this.key = key;
  }


  public getTitle(){
    switch(this.ordinal){
      case 0:

        return "Friend List"
      default :
        return "DChat"
    }
  }

}

その後、このように使用できます

HomeSlideEnum.friendList.getTitle();
2
david valentino