web-dev-qa-db-fra.com

TypeScript: ajouter des fonctions à une énumération

Est-il possible d'ajouter des fonctions à un type Enum dans TypeScript?

par exemple:

enum Mode {
    landscape,
    portrait,

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

Ou:

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

enum Mode extends ModeExtension {
    landscape,
    portrait,
}

Bien sûr, la fonction toString() contiendrait quelque chose comme un switch Mais un cas d'utilisation se déroulerait comme suit:

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

Je comprends pourquoi l'extension d'un enum peut être une chose étrange, je me demande simplement si c'est possible.

49
Mr. Baudin

Vous pouvez soit avoir une classe distincte de l'énumération et l'utiliser pour obtenir les choses que vous voulez, soit fusionner un espace de noms dans l'énumération et obtenir le tout au même endroit.

Classe utilitaire de mode

Ce n'est donc pas exactement ce que vous recherchez, mais cela vous permet d'encapsuler le comportement "Mode to string" à l'aide d'une méthode statique.

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

Vous pouvez l'utiliser comme ceci:

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

Mode Enum/Fusion d'espace de noms

Vous pouvez fusionner un espace de noms avec l'Enum afin de créer ce qui ressemble à un Enum avec des méthodes supplémentaires:

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

Vous pouvez obtenir la valeur de chaîne d'une énumération non constante en utilisant des crochets:

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

Vous pouvez également placer des fonctions util spécifiques à l'énumération dans l'énumération, mais c'est exactement comme les membres de classe statiques:

enum Mode {
    landscape,
    portrait
}

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

Convertissez votre enum en modèle d'énumération. Je trouve que c'est une meilleure pratique en général pour de nombreuses langues, car sinon vous limitez les options d'encapsulation pour votre type. La tendance est à switch sur la valeur d'énumération, alors que vraiment toutes les données ou fonctionnalités qui dépendent de la valeur d'énumération particulière devraient simplement aller dans chaque instance de l'énumération. J'ai ajouté un peu plus de code pour démontrer.

Cela peut ne pas fonctionner si vous êtes particulièrement dépendant des valeurs d'énumération sous-jacentes. Dans ce cas, vous devez ajouter un membre pour les anciennes valeurs et convertir les emplacements qui en ont besoin pour utiliser la nouvelle propriété.

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

peut faire une énumération comme par un constructeur privé et un objet de retour statique

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

}

puis plus tard peut utiliser comme ça

HomeSlideEnum.friendList.getTitle();
2
david valentino