typescript - Bir Enum'a fonksiyon ekle


TypeScript'te bir Enum türüne fonksiyon eklemek mümkün müdür?

örneğin:

enum Mode {
    landscape,
    portrait,

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

Veya :

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

enum Mode extends ModeExtension {
    landscape,
    portrait,
}

Elbette toString() fonksiyonu switch gibi bir şey içerecektir. Ama bir kullanım durumu şu şekilde ilerlerdi:

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

Enum uzatmanın garip bir şey olabileceğini anlıyorum, sadece mümkün olup olmadığını merak ediyorum.

Cevap #1

Ya Enum'dan ayrı bir sınıf oluşturup istediğiniz şeyleri almak için onu kullanabilirsiniz, ya da bir namespace'i Enum'a birleştirip hepsini aynı yerde bulabilirsiniz.

Mod Kullanışlılık Sınıfı

Yani bu tam olarak aradığınız şey değil, ama bu, "Moddan string'e" davranışını statik bir yöntem kullanarak kapsüllemenize olanak tanır.

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

Bunu şöyle kullanabilirsiniz:

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

Mod Enum/Namespace Birleştirme

Ek metodlara sahip bir Enum gibi görünen bir şey oluşturmak için bir namespace'i Enum ile birleştirebilirsiniz:

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

Cevap #2

Sabit olmayan bir enum'un string değerini köşeli parantez kullanarak alabilirsiniz:

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

Enum'in içine bazı enum-özel yardımcı fonksiyonlar da koyabilirsiniz, ama bu sadece statik sınıf üyeleri gibidir:

enum Mode {
    landscape,
    portrait
}

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

Cevap #3

enum öğenizi enum desenine dönüştürün. Genel olarak birçok dil için bunun daha iyi bir uygulama olduğunu düşünüyorum, çünkü aksi takdirde türünüz için kapsülleme seçeneklerini kısıtlarsınız. Eğilim, enum değerine switch yapmaktır; oysa belirli enum değerine bağlı herhangi bir veri veya işlevsellik, her enum örneğine gitmelidir. Bunu göstermek için biraz daha kod ekledim.

Bu, özellikle altında yatan enum değerlerine bağımlıysanız işe yaramayabilir. Bu durumda, eski değerler için bir üye eklemeniz ve gerektiğinde yeni özelliği kullanacak şekilde yerleri dönüştürmeniz gerekir.

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

Cevap #4

Fenton çözeltisine bir ek. Eğer bu numaralandırıcıyı başka bir sınıfta kullanmak istiyorsanız, hem enumu hem de ad alanını dışa aktarmanız gerekir. Şöyle görünecektir:

export enum Mode {
    landscape,
    portrait
}

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

Sonra sadece mode.enum.ts dosyasını sınıfınıza aktarır ve kullanırsınız.

İlgili makaleler