أنجولار - كيف تكتب متغير تعداد في تايب سكريبت؟


رأيت ذلك في إجابات مختلفة على StackOverflow حول كيفية الوصول إلى تعداد (enum) في HTML يُقال فيها لتعريف متغير في المكون وتعيينه مساويًا للتعداد، كما في هذا السؤال. لكن، ما سيكون النوع؟

لاستخدام مثالهم:

enum MyEnum{
  First,
  Second
}

export class MyComponent{
  MyEnum = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...
}

<div [ngSwitch]="myEnumVar">
  <div *ngSwitchCase="MyEnum.First"><app-first-component></app-first-component></div>
  <div *ngSwitchCase="MyEnum.Second"><app-second-component></app-second-component></div>
  <div *ngSwitchDefault>MyEnumVar {{myEnumVar}} is not handled.</div>
</div>

تم كتابة myEnumVar، لكن لم يتم كتابة MyEnum. فبماذا من المفترض أن أكتبه؟

الإجابة رقم 1

نظرًا لأن الـ enums تُنشأ كـ {} عادية، فإن نوعها في الواقع هو object.

على سبيل المثال، الـ enum:

enum MyEnum{
  First,
  Second
}

يتم تحويله إلى:

var MyEnum;
(function (MyEnum) {
    MyEnum[MyEnum["First"] = 0] = "First";
    MyEnum[MyEnum["Second"] = 1] = "Second";
})(MyEnum || (MyEnum = {}));
           // ^^^^^^^^^^^ --- important part

لاحظ أن MyEnum هو، في النهاية، كائن ({}) مع خصائص مضافة لاحقًا. وبشكل أكثر تحديدًا، مع مفاتيح من نوع number وقيم من نوع string (انظر المزيد أدناه).

لذا، إذا كنت ترغب في إعلان نوع، لديك بعض البدائل.

كمقدمة، يمكنك استخدام object أو any، كما هو موضح أدناه (ولكن تحقق من البدائل الأخرى أيضًا):

export class MyComponent{
  MyEnum:Object = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...
}

نوع توقيع الفهرس

خيار آخر، بالنسبة للتعدادات، يمكنك أيضًا استخدام النوع {[s: number]: number | string}:

export class MyComponent{
  MyEnum:{[s: number]: number | string} = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...
}

نوع

أو، كما أشار Gerrit0 (انظر إجابتهم للحصول على المعلومات الكاملة والاعتمادات المستحقة):

export class MyComponent{
  MyEnum:typeof MyEnum = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...
}

الإجابة رقم 2

بينما إجابة acdcjunior صحيحة من الناحية التقنية - نعم، التعداد هو كائن، ونعم يمكن وصفه بالنوع {[s: number]: string}، هذا ليس الطريقة التي يجب أن تستخدمها لتحديد نوع الخاصية MyEnum.

يتضمن التعداد قيمًا من النوع النصي والرقمي، لذلك على الأقل يجب أن يكون توقيع الفهرس { [s: number]: string | number } - MyEnum[1] === "First" بينما MyEnum.First === 1.

ومع ذلك، يوفر TypeScript طريقة أفضل للقيام بذلك، وهي عامل التشغيل typeof. هذا يختلف عن typeof في JavaScript - عندما تستخدم typeof في إعلان نوع، فإنه يحصل على نوع القيمة وليس مقيدًا بالأنواع البسيطة وobject.

لتسليط الضوء على الفرق، إليك مثال:

enum MyEnum {
  First,
  Second
}

class MyComponent {
  static MyEnum: typeof MyEnum = MyEnum
  static MyObjectEnum: { [s: number]: string | number } = MyEnum
}

// a is `any`
// can't use MyComponent.MyObjectEnum.First
let a = MyComponent.MyObjectEnum['First']
// b is `MyEnum`
let b = MyComponent.MyEnum['First'] // or MyComponent.MyEnum.First
// c is `any`
let c = MyComponent.MyObjectEnum['Third']
// d is `any`
// using MyComponent.MyEnum.Third catches this error
let d = MyComponent.MyEnum['Third']
// neither catch this error
// e is type `string`
// f is type `string | number`
let e = MyComponent.MyEnum[3]
let f = MyComponent.MyObjectEnum[3]

إذا نظرت إلى النوع الذي يستنتجه محرر الشيفرة الخاص بك عند محاولة كتابة شيء ما، يمكنك أن تتعلم الكثير عن الأنواع التي يجب استخدامها.