Was ist der Unterschied zwischen Aufzählung und Objekt in Typoskript?

Lesezeit: 5 Minuten

Ich versuche, über Enum auf Werte einer Karte zuzugreifen und auch eine übersetzungsfähige App für alle darin enthaltenen Zeichenfolgen zu erstellen. Beide Bedenken überschneiden sich und ich muss mich entscheiden, ob ich Enums oder nur Objekte im JSON-Format verwenden möchte.

Was genau ist also der Unterschied und die Verwendung zwischen einer Aufzählung und einem Objekt?

Zum Beispiel:

  • Ich kann Enums verwenden, um auf Arrays zuzugreifen sowie Labels und andere Dinge wie einzufügen
const enum FieldNames {
  FirstField: "Field One",
  SecondField: "Field Two"
};
    
someFieldArray[FieldNames.FirstField].label = FieldNames.FirstField;
someFieldArray[FieldNames.SecondField].label = FieldNames.SecondField;
  • Oder ich kann das gleiche Verhalten über das Objekt erreichen
const FieldNames = {
  FirstField: "Field One",
  SecondField: "Field Two"
};

someFieldArray[FieldNames.FirstField].label = FieldNames.FirstField;
someFieldArray[FieldNames.SecondField].label = FieldNames.SecondField;

Ich habe wirklich nicht den Vorteil, Enumerationen gegenüber einfachen Objekten zu wählen. Meiner Meinung nach hat ein Objekt viel mehr Vorteile ohne Nachteile.

Aufzählung

Eine Aufzählung kann Ihnen zusätzliche Vorteile bieten, wenn Sie die folgenden Funktionen wünschen:

const enum FieldNamesEnum {
  FirstField = "Field One",
  SecondField = "Field Two"
};

let x: FieldNamesEnum;

x = FieldNamesEnum.FirstField;
x = FieldNamesEnum.SecondField;

// Error - not assignable to FieldNames
x = 'str';

// Cannot assign
FieldNamesEnum.FirstField = 'str';

Wichtig ist, dass Sie den Aufzählungsmitgliedern keine Zuweisungen zuweisen können und Typen auf die Aufzählungsmitglieder überprüft werden und nicht auf Zeichenfolgen.

Da Sie außerdem a verwendet haben const enum In Ihrem Beispiel existiert die Aufzählung zur Laufzeit nicht und alle Referenzen werden durch die Literalwerte ersetzt (wenn Sie eine plain enum die Aufzählung möchten zur Laufzeit vorhanden).

Objekt

Vergleichen Sie dies mit dem Objektbeispiel:

const FieldNames = {
  FirstField: "Field One",
  SecondField: "Field Two"
};

let y: string;

y = FieldNames.FirstField;
y = FieldNames.SecondField;

// Oops it works
y = 'str';

// Oops it works

FieldNames.FirstField = 'str';

Union

Wenn Sie die vollständige Aufzählung nicht benötigen, aber die Werte einschränken möchten, können Sie eine Vereinigung von Literalwerten verwenden:

type FieldNames = "Field One" | "Field Two";

let x: FieldNames;

x = "Field One";
x = "Field Two";

// Error - not allowed
x = "Field Three";

  • Aber ist es möglich, gekapselte Aufzählungen zu erstellen?

    – Florian Leitgeb

    17. November 2017 um 13:34 Uhr

  • fabelhafte erklärung!! Besonders die, die sich auf die Nichtzuweisung von Enumerationsmitgliedern bezieht.

    – Shanti

    29. November 2018 um 7:15 Uhr

  • Das Problem mit Ihrer Lösung ist, dass Sie den Typ von festlegen y zu string und nicht auf die tatsächliche Art der Werte der FieldNames Objekt, das das von @Martynas Skučas unten sein sollte. Hier ist der Link: stackoverflow.com/a/59932722/1681085

    – Florian Leitgeb

    4. Februar 2020 um 15:40 Uhr

Ich stimme @Fenton nicht zu. Objekte sind typsicher.

const FieldNames = {
  FirstField: 'Field One',
  SecondField: 'Field Two',
} as const;

type ValueOf<T> = T[keyof T];
let y: ValueOf<typeof FieldNames>;

y = FieldNames.FirstField;
y = FieldNames.SecondField;

// TS2322: Type '"str"' is not assignable to type '"Field One" | "Field Two"'.
y = 'str';

// TS2540: Cannot assign to 'FirstField' because it is a read-only property
FieldNames.FirstField = 'str';

  • Ich mag dein Denken. Einstellung y Zeichenfolge einzugeben ist nicht der beste Weg. Sehr gute Antwort wie ich finde. Es beantwortet jedoch nicht die ganze Frage.

    – Florian Leitgeb

    4. Februar 2020 um 15:38 Uhr

  • as const wurde in TS 3.4 eingeführt, das 2019 veröffentlicht wurde. Und die ursprüngliche Antwort von @Fenton wurde 2017 veröffentlicht. Ich denke, dies ist eine gültige aktualisierte Antwort. Tatsächlich sagen die offiziellen TS-Dokumente das jetzt die meiste Zeit as const kann enum ersetzen.

    – kühler Gott

    18. Juni 2021 um 5:39 Uhr


  • @coolgod kannst du mir zeigen, wo in den Dokumenten steht, dass “as const enum die meiste Zeit ersetzt” steht? Ich konnte es finden.

    – Edu Ruiz

    29. Juli 2021 um 15:10 Uhr

  • @EduRuiz typescriptlang.org/docs/handbook/enums.html#objects-vs-enums

    – Robula

    21. September 2021 um 12:56 Uhr

function (foo: FieldNames) { }

Wenn FieldNames ein Objekt ist, das heißt, diese Funktion erwartet eine Instanz, die die Eigenschaften hat FirstField und SecondField. Wenn FieldNames eine Aufzählung ist (in diesem Fall sollte es Singular sein, nicht Plural), bedeutet dies, dass die Funktion erwartet einer der Werte von FieldNamesnämlich "Field One" oder "Field Two".

Sehr unterschiedliche Verwendung.

  • Aber Sie können dieses Verhalten erreichen, indem Sie einfach Schnittstellen und/oder Klassen verwenden.

    – Florian Leitgeb

    17. November 2017 um 13:11 Uhr

  • Wie definieren Sie einfach eine Schnittstelle oder Klasse, die “einen dieser Werte” sagt?

    – verzeihen

    17. November 2017 um 13:12 Uhr

  • Eine abstrakte Klasse mit statischen FieldName-Eigenschaften? Oder etwas ähnliches.

    – Florian Leitgeb

    17. November 2017 um 13:14 Uhr

  • Eine Aufzählung als Typhinweis sagt “die Variable kann einen der Werte in dieser Liste annehmen”. Eine Aufzählung als Objekt macht diese Werte leicht zugänglich durch so etwas wie Konstanten (z FieldName.FirstField); Sie können den zugrunde liegenden Wert ändern, ohne den gesamten Code, der ihn verwendet, neu schreiben zu müssen. – Das ist alles ganz anders als Klassen/Objekte, in denen Sie ein Objekt aus einer Klasse instanziieren und dieses Objekt herumreichen und einen Hinweis gegen den Objekttyp eingeben können.

    – verzeihen

    17. November 2017 um 13:20 Uhr

  • Du kannst tun function (foo: keyof FieldNames) { } stattdessen

    – Daniel Kucal

    3. Februar 2018 um 18:30 Uhr

Im Handbuch der Typescript-Sprache haben Sie einen eigenen Abschnitt, der sich damit befasst: Objekte vs. Aufzählungen.

Wenn ich einen Typ mit einer Reihe von Optionen benötige, bevorzuge ich persönlich die Verwendung von Typescript enum, da dies einfacher zu verwenden ist. Mit der Enum-Definition haben Sie den Typ und auch die Möglichkeit, auf die Optionen zuzugreifen. Um denselben Ansatz mit einem Objekt zu implementieren, müssen Sie das Objekt definieren as const und auch einen darauf basierenden zusätzlichen Typ definieren.

Dies sollte der Hauptgrund sein.

Sie können dies auch tun

type FieldNames = "Field One" | "Field Two";

aber wenn die Liste lang ist, ist Enum viel besser, in ES6 ist Enum rein nutzlos, verwenden Sie einfach obejct, aber in Typoskript ist es ein Typ und meiner Meinung nach ein Hauptvorteil

1438450cookie-checkWas ist der Unterschied zwischen Aufzählung und Objekt in Typoskript?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy