Functies toevoegen aan een Enum

Is het mogelijk om functies toe te voegen aan een Enum-type in TypeScript?

bijvoorbeeld:

enum Mode {
    landscape,
    portrait,
    // the dream...
    toString() { console.log(this); } 
}

Of:

class ModeExtension {
    public toString = () => console.log(this);
}
enum Mode extends ModeExtension {
    landscape,
    portrait,
}

Natuurlijk zou de functie toString()zoiets als een switchbevatten, maar een use-case zou in de trant van:

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

Ik begrijp waarom het verlengen van een enumvreemd kan zijn, ik vraag me alleen af ​​of het mogelijk is.


Antwoord 1, autoriteit 100%

Je kunt een klasse hebben die los staat van de Enum en deze gebruiken om dingen te krijgen die je wilt, of je kunt een naamruimte samenvoegen met de Enum en alles op dezelfde plek krijgen.

Modus Utility Class

Dit is dus niet precies wat u zoekt, maar dit stelt u in staat om het gedrag van “Modus naar tekenreeks” in te kapselen met behulp van een statische methode.

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

Je kunt het als volgt gebruiken:

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

Modus Enum/Namespace Samenvoegen

Je kunt een naamruimte samenvoegen met de Enum om te creëren wat lijkt op een Enum met aanvullende methoden:

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);

Antwoord 2, autoriteit 28%

U kunt de tekenreekswaarde van een niet-const-enum verkrijgen door vierkante haken te gebruiken:

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

Je kunt ook een aantal enum-specifieke util-functies in de enum plaatsen, maar dat is net als statische klasleden:

enum Mode {
    landscape,
    portrait
}
namespace Mode {
    export function doSomething(mode:Mode) {
        // your code here
    }
}

Antwoord 3, autoriteit 14%

Converteer uw enumnaar het enum-patroon. Ik vind dat dit in het algemeen een betere gewoonte is voor veel talen, omdat je anders de inkapselingsopties voor je type beperkt. De neiging is om switchop de enum-waarde, terwijl eigenlijk alle gegevens of functionaliteit die afhankelijk is van de specifieke enum-waarde gewoon in elke instantie van de enum zou moeten gaan. Ik heb wat meer code toegevoegd om te demonstreren.

Dit werkt mogelijk niet als u bijzonder afhankelijk bent van de onderliggende enumwaarden. In dat geval moet u een lid toevoegen voor de oude waarden en plaatsen converteren die het nodig hebben om de nieuwe eigenschap te gebruiken.

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

Antwoord 4, autoriteit 6%

Een aanvulling op de oplossing van Fenton.
Als u deze enumerator in een andere klasse wilt gebruiken, moet u zowel de opsomming als de naamruimte exporteren. Het zou er als volgt uitzien:

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

Vervolgens importeert u het bestand mode.enum.ts in uw klas en gebruikt u het.


Antwoord 5, autoriteit 2%

kan enum maken zoals door private constructor en statisch get return-object

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

dan later zo kunnen gebruiken

HomeSlideEnum.friendList.getTitle();

Other episodes