Deutsch

Entdecken Sie die Leistungsfähigkeit von TypeScript Const-Assertions für die Inferenz unveränderlicher Typen und steigern Sie die Codesicherheit und Vorhersagbarkeit in Ihren Projekten. Lernen Sie den effektiven Einsatz anhand praktischer Beispiele.

TypeScript Const-Assertions: Inferenz unveränderlicher Typen für robusten Code

TypeScript, eine Obermenge von JavaScript, bringt statische Typisierung in die dynamische Welt der Webentwicklung. Eines seiner leistungsstarken Merkmale ist die Typinferenz, bei der der Compiler automatisch den Typ einer Variable ableitet. Const-Assertions, eingeführt in TypeScript 3.4, gehen bei der Typinferenz noch einen Schritt weiter und ermöglichen es Ihnen, Unveränderlichkeit zu erzwingen und robusteren sowie vorhersagbareren Code zu erstellen.

Was sind Const-Assertions?

Const-Assertions sind eine Möglichkeit, dem TypeScript-Compiler mitzuteilen, dass ein Wert als unveränderlich beabsichtigt ist. Sie werden mit der Syntax as const nach einem literalen Wert oder Ausdruck angewendet. Dies weist den Compiler an, den engstmöglichen (literalen) Typ für den Ausdruck abzuleiten und alle Eigenschaften als readonly zu markieren.

Im Wesentlichen bieten Const-Assertions ein höheres Maß an Typsicherheit als die einfache Deklaration einer Variable mit const. Während const eine Neuzuweisung der Variable selbst verhindert, unterbindet es nicht die Änderung des Objekts oder Arrays, auf das die Variable verweist. Const-Assertions verhindern auch die Änderung der Eigenschaften des Objekts.

Vorteile der Verwendung von Const-Assertions

Praktische Beispiele

Beispiel 1: Grundlegende Verwendung mit einem Literal

Ohne eine Const-Assertion leitet TypeScript den Typ von message als string ab:


const message = "Hello, World!"; // Type: string

Mit einer Const-Assertion leitet TypeScript den Typ als den literalen String "Hello, World!" ab:


const message = "Hello, World!" as const; // Type: "Hello, World!"

Dies ermöglicht es Ihnen, den literalen String-Typ in präziseren Typdefinitionen und Vergleichen zu verwenden.

Beispiel 2: Verwendung von Const-Assertions mit Arrays

Betrachten wir ein Array von Farben:


const colors = ["red", "green", "blue"]; // Type: string[]

Obwohl das Array mit const deklariert ist, können Sie seine Elemente dennoch ändern:


colors[0] = "purple"; // No error
console.log(colors); // Output: ["purple", "green", "blue"]

Durch Hinzufügen einer Const-Assertion leitet TypeScript das Array als ein Tupel von schreibgeschützten Strings ab:


const colors = ["red", "green", "blue"] as const; // Type: readonly ["red", "green", "blue"]

Der Versuch, das Array jetzt zu ändern, führt zu einem TypeScript-Fehler:


// colors[0] = "purple"; // Error: Index signature in type 'readonly ["red", "green", "blue"]' only permits reading.

Dies stellt sicher, dass das colors-Array unveränderlich bleibt.

Beispiel 3: Verwendung von Const-Assertions mit Objekten

Ähnlich wie Arrays können auch Objekte mit Const-Assertions unveränderlich gemacht werden:


const person = {
  name: "Alice",
  age: 30,
}; // Type: { name: string; age: number; }

Selbst mit const können Sie die Eigenschaften des person-Objekts noch ändern:


person.age = 31; // No error
console.log(person); // Output: { name: "Alice", age: 31 }

Das Hinzufügen einer Const-Assertion macht die Eigenschaften des Objekts readonly:


const person = {
  name: "Alice",
  age: 30,
} as const; // Type: { readonly name: "Alice"; readonly age: 30; }

Der Versuch, das Objekt jetzt zu ändern, führt zu einem TypeScript-Fehler:


// person.age = 31; // Error: Cannot assign to 'age' because it is a read-only property.

Beispiel 4: Verwendung von Const-Assertions mit verschachtelten Objekten und Arrays

Const-Assertions können auf verschachtelte Objekte und Arrays angewendet werden, um tiefgreifend unveränderliche Datenstrukturen zu schaffen. Betrachten Sie das folgende Beispiel:


const config = {
  apiUrl: "https://api.example.com",
  endpoints: {
    users: "/users",
    products: "/products",
  },
  supportedLanguages: ["en", "fr", "de"],
} as const;

// Type:
// {
//   readonly apiUrl: "https://api.example.com";
//   readonly endpoints: {
//     readonly users: "/users";
//     readonly products: "/products";
//   };
//   readonly supportedLanguages: readonly ["en", "fr", "de"];
// }

In diesem Beispiel sind das config-Objekt, sein verschachteltes endpoints-Objekt und das supportedLanguages-Array alle als readonly markiert. Dies stellt sicher, dass kein Teil der Konfiguration zur Laufzeit versehentlich geändert werden kann.

Beispiel 5: Const-Assertions bei Funktionsrückgabetypen

Sie können Const-Assertions verwenden, um sicherzustellen, dass eine Funktion einen unveränderlichen Wert zurückgibt. Dies ist besonders nützlich bei der Erstellung von Hilfsfunktionen, die ihre Eingaben nicht ändern oder veränderbare Ausgaben erzeugen sollten.


function createImmutableArray(items: T[]): readonly T[] {
  return [...items] as const;
}

const numbers = [1, 2, 3];
const immutableNumbers = createImmutableArray(numbers);

// Type of immutableNumbers: readonly [1, 2, 3]

// immutableNumbers[0] = 4; // Error: Index signature in type 'readonly [1, 2, 3]' only permits reading.

Anwendungsfälle und Szenarien

Konfigurationsmanagement

Const-Assertions sind ideal für die Verwaltung der Anwendungskonfiguration. Indem Sie Ihre Konfigurationsobjekte mit as const deklarieren, können Sie sicherstellen, dass die Konfiguration während des gesamten Lebenszyklus der Anwendung konsistent bleibt. Dies verhindert versehentliche Änderungen, die zu unerwartetem Verhalten führen könnten.


const appConfig = {
  appName: "My Application",
  version: "1.0.0",
  apiEndpoint: "https://api.example.com",
} as const;

Definition von Konstanten

Const-Assertions sind auch nützlich, um Konstanten mit spezifischen literalen Typen zu definieren. Dies kann die Typsicherheit und die Klarheit des Codes verbessern.


const HTTP_STATUS_OK = 200 as const; // Type: 200
const HTTP_STATUS_NOT_FOUND = 404 as const; // Type: 404

Arbeiten mit Redux oder anderen State-Management-Bibliotheken

In State-Management-Bibliotheken wie Redux ist Unveränderlichkeit ein Kernprinzip. Const-Assertions können helfen, die Unveränderlichkeit in Ihren Reducern und Action Creators durchzusetzen und unbeabsichtigte Zustandsmutationen zu verhindern.


// Example Redux reducer

interface State {
  readonly count: number;
}

const initialState: State = { count: 0 } as const;

function reducer(state: State = initialState, action: { type: string }): State {
  switch (action.type) {
    default:
      return state;
  }
}

Internationalisierung (i18n)

Bei der Arbeit mit Internationalisierung haben Sie oft eine Reihe von unterstützten Sprachen und deren entsprechende Locale-Codes. Const-Assertions können sicherstellen, dass dieser Satz unveränderlich bleibt, und verhindern so versehentliche Ergänzungen oder Änderungen, die Ihre i18n-Implementierung beeinträchtigen könnten. Stellen Sie sich zum Beispiel vor, Sie unterstützen Englisch (en), Französisch (fr), Deutsch (de), Spanisch (es) und Japanisch (ja):


const supportedLanguages = ["en", "fr", "de", "es", "ja"] as const;

type SupportedLanguage = typeof supportedLanguages[number]; // Type: "en" | "fr" | "de" | "es" | "ja"

function greet(language: SupportedLanguage) {
  switch (language) {
    case "en":
      return "Hello!";
    case "fr":
      return "Bonjour!";
    case "de":
      return "Guten Tag!";
    case "es":
      return "¡Hola!";
    case "ja":
      return "こんにちは!";
    default:
      return "Greeting not available for this language.";
  }
}

Einschränkungen und Überlegungen

Alternativen zu Const-Assertions

Obwohl Const-Assertions ein mächtiges Werkzeug zur Durchsetzung der Unveränderlichkeit sind, gibt es andere Ansätze, die Sie in Betracht ziehen können:

Best Practices

Fazit

TypeScript Const-Assertions sind ein wertvolles Werkzeug, um Unveränderlichkeit durchzusetzen und die Typsicherheit in Ihrem Code zu verbessern. By using as const, you can instruct the compiler to infer the narrowest possible type for a value and mark all properties as readonly. Dies kann helfen, unbeabsichtigte Änderungen zu verhindern, die Vorhersagbarkeit des Codes zu verbessern und eine präzisere Typüberprüfung zu ermöglichen. Obwohl Const-Assertions einige Einschränkungen haben, sind sie eine leistungsstarke Ergänzung zur TypeScript-Sprache und können die Robustheit Ihrer Anwendungen erheblich verbessern.

Indem Sie Const-Assertions strategisch in Ihre TypeScript-Projekte integrieren, können Sie zuverlässigeren, wartbareren und vorhersagbareren Code schreiben. Nutzen Sie die Kraft der Inferenz unveränderlicher Typen und heben Sie Ihre Softwareentwicklungspraktiken auf ein neues Niveau.