Menu

TypeScript Typalias: das Schlüsselwort type mit Beispielen

Ein Typalias gibt jedem Typ mit dem Schlüsselwort type einen Namen: Objektformen, Unions, Tupeln, Funktionen, Generics und rekursiven Typen. Die Syntax, wie jede Form aussieht und warum ein Alias nur ein Name ist und kein neuer, eigenständiger Typ.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Ein Typalias gibt einem Typ einen Namen. Du schreibst type Name = ..., und von da an lässt sich Name überall verwenden, wo ein Typ erwartet wird. Anders als ein Interface kann ein Alias jeden beliebigen Typ benennen, nicht nur Objektformen.

Aliasse existieren nur beim Kompilieren. Das erzeugte JavaScript enthält keine dieser type-Zeilen.

Syntax

type Name = SomeType;
type Name<T> = SomeTypeUsing<T>;       // generic
export type Name = SomeType;           // exported from a module

Namen werden per Konvention in PascalCase geschrieben. Die rechte Seite ist ein beliebiger Typausdruck, und ein Alias kann andere Aliasse verwenden, auch sich selbst (siehe rekursive Typen unten). Der Alias ist im ganzen Scope verfügbar, in dem er deklariert ist, sogar oberhalb der Deklarationszeile, denn Typen werden beim Kompilieren geprüft und nicht der Reihe nach ausgeführt wie const oder let.

Objekttypen

Für eine Objektform werden Alias und Interface fast gleich geschrieben. Der Alias verwendet = und endet meist mit einem Semikolon.

Ein Alias kann kein extends verwenden; die Intersection mit & übernimmt diese Rolle. Excess Property Checks, optionale und readonly Eigenschaften funktionieren genau wie bei Interfaces. Welche der beiden Formen du für Objektformen wählst, behandelt die Seite interface vs type.

Unions, Tupel und Funktionen

Das sind die Fälle, die nur ein Alias benennen kann, und der Hauptgrund, warum es type gibt. Ein Union-Alias listet die Alternativen auf, ein Tupel-Alias legt Länge und Elementtypen eines Arrays fest, und ein Funktionsalias beschreibt eine Signatur.

In scale brauchen die Parameter keine Annotationen: Der Alias Transform liefert ihre Typen. Die Syntax von Tupeln steht unter Tupel, das Einengen von Unions auf der Seite zu Union-Typen.

Generische Typaliasse

Typparameter lassen einen Alias für viele Typen funktionieren. Sie können Standardwerte haben, genau wie Funktionsparameter.

Result<number> verwendet den Standardwert E = string. Kleine generische Aliasse wie type Nullable<T> = T | null oder type Dict<T> = Record<string, T> sind in echtem Code verbreitet. Auch die eingebauten Utility Types (Partial<T>, Pick<T, K>, ReturnType<F>) sind generische Aliasse, deklariert in der Standardbibliothek.

Aliasse sind Namen, keine neuen Typen

Ein Alias erzeugt keinen eigenständigen Typ. Er ist ein zweiter Name für den Typ auf der rechten Seite, und der Compiler behandelt beide als identisch. Zwei Aliasse von string sind vollständig austauschbar:

Das gibt cancelling u_42 ohne Fehler aus, und genau diesen Bug kann ein Alias nicht verhindern. Der Alias hilft trotzdem beim Lesen (ein als OrderId typisierter Parameter sagt mehr als string), aber wenn das Verwechseln zweier IDs ein Compilerfehler sein muss, nimm einen Branded Type wie string & { readonly __brand: "OrderId" }.

Rekursive Typaliasse

Ein Alias kann auf sich selbst verweisen, und so beschreibst du Bäume, verschachtelte Listen und JSON:

Der Alias Json lehnt Werte ab, die JSON nicht darstellen kann: { when: new Date() } oder { f: undefined } einer Variablen vom Typ Json zuzuweisen sind Compilerfehler (TS2322).

Typen aus Werten: typeof

Wenn ein Wert schon existiert, kannst du seinen Typ benennen, statt ihn auszuschreiben. Der Typoperator typeof liest den Typ einer Variablen, und er lässt sich mit anderen Operatoren kombinieren:

const defaults = { retries: 3, verbose: false, level: "info" };

type Options = typeof defaults;
// { retries: number; verbose: boolean; level: string }

type OptionKey = keyof typeof defaults;
// "retries" | "verbose" | "level"

function start(port: number) {
  return { port, startedAt: new Date() };
}
type Server = ReturnType<typeof start>;
// { port: number; startedAt: Date }

Der Wert bleibt die einzige Quelle der Wahrheit: Füge defaults eine Eigenschaft hinzu, und Options folgt. Mehr dazu unter typeof.

Aliasse exportieren und importieren

Aliasse werden wie Werte exportiert und importiert. import type macht ausdrücklich, dass nur ein Typ importiert wird, sodass der Import immer aus der JavaScript-Ausgabe entfernt wird:

// shapes.ts
export type Point = { x: number; y: number };
export type Shape = { kind: "circle"; center: Point; radius: number };

// main.ts
import type { Point, Shape } from "./shapes.js";

const p: Point = { x: 1, y: 2 };

Häufig gestellte Fragen

Was ist ein Typalias in TypeScript?

Ein Typalias ist ein Name für einen Typ, deklariert mit dem Schlüsselwort type: type Point = { x: number; y: number }. Danach kann Point überall verwendet werden, wo ein Typ erwartet wird. Er kann jeden Typ benennen: eine Objektform, eine Union, ein Tupel, eine Funktionssignatur, einen primitiven Typ oder einen generischen Typ.

Erzeugt ein Typalias einen neuen Typ?

Nein. Ein Alias ist nur ein weiterer Name für einen vorhandenen Typ. Mit type UserId = string und type OrderId = string kann eine UserId übergeben werden, wo eine OrderId erwartet wird, weil beide einfach string sind. Für Typen, die nicht austauschbar sein sollen, nimm einen Branded Type.

Kann ein Typalias auf sich selbst verweisen?

Ja, solange der Selbstverweis in einem Objekttyp, einem Array oder einem Tupel steckt: type TreeNode = { value: number; children: TreeNode[] } und ein Alias Json, der Json[] enthält, funktionieren beide. Ein nackter Verweis wie type Loop = Loop | string ist der Fehler TS2456, Type alias 'Loop' circularly references itself.

Kann ein Typalias generisch sein?

Ja. Setze Typparameter hinter den Namen: type Box<T> = { value: T } und verwende ihn dann als Box<number>. Parameter können Standardwerte (type Result<T, E = string> = ...) und Constraints (type Keys<T extends object> = keyof T) haben.

Wie bekomme ich einen Typ aus einem vorhandenen Objekt?

Mit dem Typoperator typeof: const defaults = { retries: 3, verbose: false }; type Options = typeof defaults; ergibt { retries: number; verbose: boolean }. So bleibt es bei einer einzigen Quelle der Wahrheit, wenn der Wert zuerst da ist.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S