So benötigen Sie eine bestimmte Zeichenfolge in der TypeScript-Oberfläche


144

Ich erstelle eine TypeScript-Definitionsdatei für eine JS-Bibliothek eines Drittanbieters. Eines des Verfahrens ermöglicht ein Optionen - Objekt und eine der Eigenschaften des Objekts Optionen akzeptiert eine Zeichenfolge aus der Liste: "collapse", "expand", "end-expand", und "none".

Ich habe eine Schnittstelle für das Optionsobjekt:

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style?: // "collapse" | "expand" | "end-expand" | "none"
}

Kann die Schnittstelle dies erzwingen ? Wenn Sie also ein IOptionsObjekt in die brace_styleEigenschaft aufnehmen, wird nur eine Zeichenfolge zugelassen, die in der zulässigen Liste enthalten ist.


4
Bitte überprüfen Sie die Antworten auf diese Frage
Andreas

In Anlehnung an den Kommentar von @Andreas, warum bevorzugen Sie die Antwort von RyanQ gegenüber der von Denis Khay ? Denis 'scheint imo breiter anwendbar zu sein.
Ruffin

Antworten:


226

Dies wurde in Version 1.8 als "String-Literal-Typen" veröffentlicht.

Was ist neu in Typescript - String Literal Types

Beispiel von der Seite:

interface AnimationOptions {
  deltaX: number;
  deltaY: number;
  easing: "ease-in" | "ease-out" | "ease-in-out";
}

6
Es erfordert das Kopieren und Einfügen von Zeilen mit Zeichenfolgen, wo immer in der App Sie Zeichenfolgen dieses Typs als Argument übergeben müssen. Wenn Sie immer ganze AnimationOptions verwenden, scheint diese Lösung in Ordnung zu sein, aber für Anwendungsfälle, in denen Sie möglicherweise nur den Typ "Beschleunigung" übergeben, ist dies falsch. Siehe Denis Khay Antwort, es ist weitaus besser.
Patryk Wlaź

121

Versuche dies

export type ReadingTypes = 'some'|'variants'|'of'|'strings';

export interface IReadings {
   param:ReadingTypes
}

12
Dies sollte als korrekt markiert werden, da der erstellte Typ an einer beliebigen Stelle in einer Anwendung wiederverwendet werden kann.
Patryk Wlaź

Dies ist genau das, wonach ich gesucht habe, um ein Array von Zeichenfolgen als Werte an einen Aufzählungstyp zu übergeben. Durch vollständiges Überspringen und Verwenden von Enum typekonnte ich das folgende Beispiel übergeben: const myVar: ReadingTypes = ["some"|"variants"];unter Beibehaltung einer dynamischen Enum-Typisierungssyntax. Völlig einverstanden, dass dies die als richtig gekennzeichnete Antwort gewesen sein sollte.
Mdawsondev

Gibt es eine Möglichkeit, dies zu verwenden, aber so sanft getippt, type VisibilityTypes = VISIBILITY.PUBLISH | VISBIBILITY.DRAFTerhalte ich einen Namespace-Fehler, der nicht gefunden wurde. Wenn ich sie jedoch hart codiere, scheint es zu funktionieren
Max Carroll

Ich fand einen Weg und fügte eine neue Antwort hinzu
Max Carroll

10

Vielleicht nicht genau das, was Sie wollten, aber es Enumscheint eine perfekte Lösung für Sie zu sein.

enum BraceStyle {Collapse, Expand, EndExpand, None}

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style?: BraceStyle
}

Aufzählungen basieren jedoch auf Zahlen. BraceStyle.CollapseDies bedeutet, dass zur Laufzeit in diesem Fall ein realer Wert für z. B. 0 ist. Sie können sie jedoch auch mit anderen Skripten verwenden, die keine Typoskripte sind, da sie zu Objekten kompiliert werden. So sieht BraceStyledas Kompilieren und Ausführen aus:

{
    0: "Collapse",
    1: "Expand",
    2: "EndExpand",
    3: "None",
    Collapse: 0,
    Expand: 1,
    EndExpand: 2,
    None: 3
}

Wenn Sie stattdessen Zeichenfolgen möchten, können Sie eine Klasse mit statischen Elementen verwenden, wie hier beschrieben


enums können Zeichenfolgenwerte haben (zumindest jetzt nicht sicher, ob dies 2014 möglich ist). enum BraceStyle { Collapse = "Collapse", Expand = "Expand" }.
ZachB

Wenn sie es 2014 könnten, würde ich das in meiner Antwort erwähnen.
Kuba Jagoda

8

TS bietet eine Typisierung für bestimmte Zeichenfolgenwerte an, die als Zeichenfolgenliteraltypen bezeichnet werden .

Hier ist ein Beispiel für deren Verwendung:

type style =  "collapse" | "expand" | "end-expand" | "none";

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style1?:  "collapse" | "expand" | "end-expand" | "none";
  brace_style2?:  style;
}

// Ok
let obj1: IOptions = {brace_style1: 'collapse'};

// Compile time error:
// Type '"collapsessss"' is not assignable to type '"collapse" | "expand" | "end-expand" | "none" | undefined'.
let obj2: IOptions = {brace_style1: 'collapsessss'};

1
function keysOf<T>(obj: T, key: keyof T) { return obj[key]; }
interface SomeInterface {
   a: string;
}
const instance: SomeInterface = { a: 'some value'};
let value = keysOf<SomeInterface>(instance, 'b'); // invalid
value =  keysOf<SomeInterface>(instance, 'a'); // valid

1

Ab TypeScript 2.4 können Sie String Enums verwenden

Ich bevorzuge diesen Ansatz, weil dadurch vermieden wird, dass dieselbe fest codierte Zeichenfolge an mehr als einer Stelle vorhanden sein muss.

Es ist möglich, eine Aufzählung zu erstellen, bei der die Werte Zeichenfolgen sind

export enum VISIBILITY {
  PUBLISH = "publish",
  DRAFT = "draft"
}

Diese Aufzählung kann dann als Typ für eine Schnittstelle oder Klasse verwendet werden

export interface UserOptions  {
  visibility:  VISIBILITY 
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.