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.
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.
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);
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);
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
}
}
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;
}
}
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();