Menu

TypeScript Objekttypen: optionale und readonly Eigenschaften

Objekte in TypeScript typisieren: Inline-Objekttypen, optionale Eigenschaften mit ?, readonly Eigenschaften, verschachtelte Objekte, Methoden, Excess Property Checks und der Unterschied zwischen object, {} und Object.

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

Ein TypeScript-Objekttyp listet die Eigenschaften eines Objekts und den Typ jeder Eigenschaft auf: { name: string; age: number }. Mit ? machst du eine Eigenschaft optional, mit readonly verhinderst du, dass sie neu zugewiesen wird. Schreibe den Typ inline oder benenne ihn mit type oder interface, um ihn wiederzuverwenden.

Objekttypen schreiben

Eigenschaften werden durch ; oder , getrennt (beides funktioniert, ; ist der übliche Stil), und ein Zeilenumbruch allein reicht auch. Ein Inline-Typ ist für einen einmaligen Parameter in Ordnung; alles, was zweimal verwendet wird, bekommt einen Namen.

// Inline, in a parameter
function area(rect: { width: number; height: number }): number {
    return rect.width * rect.height;
}

// Named with a type alias
type Rect = { width: number; height: number };

// Named with an interface (the same shape)
interface RectShape {
    width: number;
    height: number;
}

type und interface beschreiben Objektformen gleich gut. Die Unterschiede (Declaration Merging, Unions) stehen auf der Seite interface vs type.

Auf eine Eigenschaft zuzugreifen, die der Typ nicht deklariert, ist ein Compilerfehler: point.z ergibt TS2339, Property 'z' does not exist on type '{ x: number; y: number; }'.

Optionale Eigenschaften

Ein ? hinter dem Namen erlaubt, die Eigenschaft wegzulassen. Eine optionale Eigenschaft zu lesen ergibt T | undefined, daher zwingt dich TypeScript, den fehlenden Fall zu behandeln, bevor du sie verwendest.

Eine Methode auf einer optionalen Eigenschaft ohne Prüfung aufzurufen ist ein Fehler: p.nickname.toUpperCase() scheitert mit TS18048, 'p.nickname' is possibly 'undefined'. Nutze Optional Chaining (p.nickname?.toUpperCase()), wenn undefined ein akzeptables Ergebnis ist.

prop?: T und prop: T | undefined sind nicht dasselbe. Das erste erlaubt, dass der Schlüssel fehlt; das zweite verlangt den Schlüssel, auch wenn sein Wert undefined sein darf:

Readonly Eigenschaften

readonly verhindert, dass eine Eigenschaft nach dem Erzeugen des Objekts neu zugewiesen wird. Es ist nur eine Prüfung beim Kompilieren, und sie ist flach: Ein Objekt oder Array in einer readonly Eigenschaft kann innen trotzdem verändert werden.

Die Ausgabe zeigt beide Grenzen: Die id hat sich zur Laufzeit wirklich geändert (nur der Compiler wusste, dass sie readonly ist), und das Array darin wurde verändert. Für ein readonly Array nimmst du readonly string[]; um alle Eigenschaften auf einmal readonly zu machen, Readonly<Order>.

Excess Property Checks

Weist du ein Objektliteral direkt einer typisierten Variablen zu oder übergibst es direkt an einen typisierten Parameter, lehnt TypeScript jede Eigenschaft ab, die der Typ nicht deklariert. Zusätzliche Eigenschaften in einem frischen Literal sind fast immer Tippfehler.

index.ts(8,8): error TS2561: Object literal may only specify known properties, but 'colour' does not exist in type 'Options'. Did you mean to write 'color'?

Der Code ist TS2561, weil der Compiler einen ähnlichen Namen gefunden hat; eine zusätzliche Eigenschaft ohne ähnlichen Namen ergibt TS2353, Object literal may only specify known properties, and 'z' does not exist in type 'Point'. Ohne die Prüfung würde der Tippfehler kompilieren, color wäre undefined, und das Programm würde stillschweigend in Schwarz zeichnen. Die Prüfung gilt nur für frische Literale. Ein Objekt, das schon in einer Variablen liegt, darf zusätzliche Eigenschaften haben, denn TypeScript typisiert strukturell: Ein Wert passt zu einem Typ, wenn er mindestens die geforderten Eigenschaften hat.

Verschachtelte Objekte und Methoden

Objekttypen lassen sich verschachteln, und sie können Methoden beschreiben, entweder in Methodensyntax oder als Eigenschaft mit Funktionstyp.

Bei tiefen oder wiederverwendeten Formen benennst du den inneren Typ (type Address = { ... }) und verweist darauf, oder du holst ihn per Indexed Access aus dem äußeren Typ, Company["address"], wie es die letzten Zeilen tun.

object vs {} vs Object

Drei Typen klingen ähnlich und bedeuten Verschiedenes:

TypAkzeptiertLehnt ab
objectjeden nicht primitiven Wert: {}, [], Funktionen, Klasseninstanzen5, "a", true, null, undefined
{}jeden Wert außer null und undefined, primitive eingeschlossennull, undefined
Objectdasselbe wie {}, plus eine Prüfung, dass eingebaute Member wie toString kompatible Typen behaltennull, undefined
{ x: number }jeden Wert mit einem numerischen xWerte ohne x

{} bedeutet nicht „ein leeres Objekt“, sondern „nicht null oder undefined“. Um ein beliebiges Objekt mit unbekannten Schlüsseln zu akzeptieren, nimm Record<string, unknown>; für eine Zuordnung von Schlüsseln zu Werten eine Index-Signatur oder Record, wie auf der Seite zum Dictionary gezeigt. Meistens ist eine konkrete Form besser als jeder der drei.

Häufig gestellte Fragen

Wie definiert man in TypeScript einen Objekttyp?

Liste die Eigenschaften und ihre Typen in geschweiften Klammern auf: { name: string; age: number }. Du kannst ihn inline in einer Annotation schreiben oder ihm mit type User = { ... } oder interface User { ... } einen Namen geben und ihn wiederverwenden. Trenne Eigenschaften mit ; oder ,.

Wie macht man in TypeScript eine Eigenschaft optional?

Setze ? hinter den Eigenschaftsnamen: { name: string; nickname?: string }. Das Objekt darf nickname weglassen, und beim Lesen erhältst du string | undefined, also musst du prüfen oder einen Standardwert angeben (user.nickname ?? user.name), bevor du es als String verwendest.

Was ist der Unterschied zwischen prop?: string und prop: string | undefined?

Bei prop?: string darf der Schlüssel komplett fehlen. Bei prop: string | undefined ist der Schlüssel Pflicht, auch wenn sein Wert undefined sein darf, also ist {} ein Compilerfehler. Beim Lesen ergeben beide string | undefined.

Was ist der Unterschied zwischen object, {} und Object in TypeScript?

object bedeutet jeden nicht primitiven Wert (Objekte, Arrays, Funktionen) und lehnt 5 oder "a" ab. {} bedeutet jeden Wert außer null und undefined, primitive eingeschlossen. Object ist fast dasselbe wie {}, prüft aber zusätzlich, dass eingebaute Methoden wie toString kompatible Typen behalten. Nimm object oder besser eine konkrete Form statt {} oder Object.

Warum meldet TypeScript, ein Objektliteral dürfe nur bekannte Eigenschaften angeben?

Das ist der Excess Property Check: Fehler TS2353 oder TS2561, wenn der Compiler die vermutlich gemeinte Eigenschaft vorschlagen kann. Weist du ein frisches Objektliteral direkt einer typisierten Variablen oder einem Parameter zu, wird jede Eigenschaft markiert, die der Typ nicht deklariert, weil das meist ein Tippfehler ist. Ein Objekt aus einer anderen Variablen zuzuweisen umgeht die Prüfung, da strukturelle Typisierung zusätzliche Eigenschaften erlaubt.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S