
Grundlegende Typen und Operationen mit Typen
Einfaches Interface
interface Foo { x: number } // Foo definiert einen Objekttyp
Deklarationen mergen
interface Foo { x: number } interface Foo { y: string } // Foo ist { x: number, y: string } // Multiple Interface-Deklarationen // werden zusammengeführt
Globales Window-Objekt durch Zusammenführen von Deklarationen erweitern
declare global { interface Window { foo: string; } } // Window wurde um das // Property foo erweitert
Type Alias
type Foo = number; // Foo ist ein Alias für number type Bar = { x: number }; // Bar definiert einen neuen Objekttyp type Baz = [number]; // Baz definiert einen neuen unären Tuple Type
Zur Erinnerung: Ein Type Alias ist unter fast allen Umständen dasselbe wie eine Interfacedeklaration. Nur Interfaces unterstützen das Zusammenführen von Deklarationen und können somit globale Typen erweitern.
Generic Types
type Foo <T> = { x: T }; // Verpackt einen Typ T in ein Objekt type Bar <T, U> = [ T, U ]; // Verpackt die Typen T und U in einen Tuple Type
Hinweis: Sie können sich Generic Types als Type Factories vorstellen. Sie sind technisch gesehen Typen, erzeugen aber nur dann wirklich brauchbare Typen, wenn sie mit einem Typparameter „aufgerufen“ werden – so wie JavaScript-Funktionen technisch gesehen Werte sind, ihr primärer Anwendungsfall aber darin besteht, eine Factory für andere Werte zu sein.
Variadic Tuple Type
type Foo = [number, string]; type Bar = [boolean]; type Res = [...Foo, ...Bar, 42]; // Res ist [number, string, boolean, 42] // funktioniert genau wie der spread-Operator // in JavaScript
Index Type
type Foo = { bar: number }; type BarOfFoo = Foo["bar"]; // BarOfFoo ist number (wird aus Foo extrahiert)
Type Query (Typinfo aus Runtime-Objekten extrahieren)
let myObject = { x: 42 }; // Der Typ von myObject wird abgeleitet type MyObjectType = typeof myObject; // Die Typart von myObject ausgeben, // das ist: { x: number }
Hinweis: typeof an einer Typposition ist etwas völlig anderes als typeof an einer Wertposition.
const Assertion
let myFoo = { x: 42 }; type Foo = typeof myFoo; // Foo ist { x: number } let myBar = { x: 42 } as const; type Bar = typeof myBar; // Bar ist { readonly x: 42 }
Hinweis: Eine const Assertion schränkt einen Typ so weit wie möglich ein, während die standardmäßige Typinferenz einen Typ so weit wie möglich erweitert. Sie funktioniert wie eine Typ-Assertion, die den engstmöglichen Typ angibt, dem ein Wert zuweisbar ist.
Index Type Query (extrahiert die Feldtypen eines Objekttypen)
type Foo = { x: number, y: string }; type FooKeys = keyof Foo; // FooKeys ist "x" | "y"
Union Type (Set der Fähigkeiten mehrerer Typen)
type Foo = { x: number, y: boolean }; type Bar = { x: number, z: string }; type FooBar = Foo | Bar; // FooBar hat nur Faehigkeiten, die // sowohl bei Foo als auch bei Bar vorhanden sind. // Foo und Bar sind Subtypen von FooBar // und sind somit FooBar zuweisbar.
Zur Erinnerung: Das Typsystem von TypeScript kümmert sich nur um die Fähigkeiten eines Typs und nicht um die Identität des Typs (strukturelle Subtypisierung).
Objekttypen mit Unions indexieren
type Keys = "x" | "y"; type Foo = { x: number; y: boolean; z: string }; type Vals = Foo[Keys] // Vals hat den Typ number | boolean
Objekttypen mit ihren eigenen Keys indexieren
type Foo = { x: number; y: boolean; z: string; }; type Vals = Foo[keyof Foo] // Vals entspricht number | boolean | string // Unions rein, Unions raus!
Hinweis: Sie können sich jeden Typ in Ihrem gesamten Programm als Unions vorstellen – es ist nur so, dass die meisten dieser Unions zufällig die Größe 1 haben.
Intersection Type (Kombination der Fähigkeiten mehrerer Typen)
type Foo = { x: number, y: boolean }; type Bar = { x: number, z: string }; type FooBar = Foo & Bar; // FooBar hat alle Faehigkeiten // von Foo und Bar // FooBar ist ein Subtype von Foo und Bar // und kann somit beiden zugewiesen werden
Union und Intersection Types kombinieren
type A = number | string & any[]; // A ist number | ...