Menu

TypeScript Funktionen: Parameter, Rückgabetyp und void

Funktionen in TypeScript typisieren: jeden Parameter annotieren, den Rückgabetyp annotieren oder ableiten lassen, void für Funktionen ohne Rückgabewert verwenden und Arrow Functions, Funktionsausdrücke, async-Funktionen und den this-Parameter typisieren.

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

Eine TypeScript-Funktion ist eine JavaScript-Funktion mit Typen an ihren Parametern und optional an ihrem Rückgabewert. Jeder Parameter bekommt eine Annotation, der Rückgabetyp steht hinter der Parameterliste, und der Compiler prüft jeden Aufruf gegen beides.

Beide fehlerhaften Aufrufe sind Fehler beim Kompilieren (TS2345 und TS2554). Die Kommentare // @ts-expect-error sagen dem Compiler, dass in der nächsten Zeile ein Fehler erwartet wird, damit der Rest der Datei trotzdem läuft. Entferne einen davon und führe erneut aus, um die echte Meldung zu sehen.

Parametertypen

Jeder Parameter wird als name: Type geschrieben. Unter strict, das in TypeScript 7 standardmäßig aktiv ist, ist ein Parameter ohne Annotation und ohne Kontext, aus dem sich ableiten ließe, ein Fehler: Parameter 'x' implicitly has an 'any' type. (TS7006). In der Praxis wird also jeder Parameter einer eigenständigen Funktion annotiert.

Jeder Typ kann Parametertyp sein: primitive Typen, Arrays, Objekttypen, Unions, andere Funktionen.

TypeScript prüft auch die Anzahl der Argumente. Mehr oder weniger zu übergeben, als die Funktion deklariert, ist ein Fehler, anders als in reinem JavaScript, das fehlende mit undefined auffüllt und überzählige ignoriert. Wie du einen Parameter optional machst oder ihm einen Standardwert gibst, steht unter optionale Parameter.

Rückgabetypen: annotieren oder ableiten

Der Rückgabetyp folgt auf die schließende Klammer: function f(): Type. Er ist optional. Ohne ihn leitet TypeScript den Typ aus jedem return im Rumpf ab.

Eine Annotation lohnt sich, wenn die Funktion exportiert wird, mehrere Rückgabepfade hat oder rekursiv ist. Der Fehler erscheint dann in der Funktion, beim falschen return, statt bei einem Aufrufer. Ein klassischer Fall ist ein Zweig, der das Zurückgeben vergisst:

Der Compiler meldet index.ts(2,32): error TS2366: Function lacks ending return statement and return type does not include 'undefined'. Ergänze am Ende return "C";, und es läuft. Ohne die Annotation : string würde die Funktion mit dem abgeleiteten Typ "A" | "B" | undefined kompilieren, und das Problem würde zu dem wandern, der das Ergebnis verwendet.

void: Funktionen ohne Rückgabewert

Eine Funktion, die nur etwas tut (loggt, schreibt, verändert), hat den Rückgabetyp void. Das leitet TypeScript ab, wenn es kein return mit Wert gibt, und du kannst es auch ausdrücklich schreiben.

Diese Regeln zu void überraschen viele:

SituationErlaubt?
function f(): void { return 42; }Nein: Type 'number' is not assignable to type 'void'. (TS2322)
const f: () => void = () => 42;Ja: Der Wert wird zurückgegeben, aber Aufrufer dürfen sich nicht darauf verlassen
function f(): undefined {}Ja (ab TypeScript 5.1)
Das Ergebnis einer void-Funktion in einem if verwendenNein: An expression of type 'void' cannot be tested for truthiness. (TS1345)

Die zweite Zeile ist Absicht. Deshalb kompiliert arr.forEach(x => list.push(x)), obwohl push eine Zahl zurückgibt. void in einem Funktionstyp bedeutet: Was auch immer das zurückgibt, niemand liest es. Für eine Funktion, die nie zurückkehrt (sie wirft immer oder läuft endlos), ist der Rückgabetyp never.

Arrow Functions und Funktionsausdrücke

Arrow Functions und Funktionsausdrücke nehmen dieselben Annotationen. Der Rückgabetyp steht hinter der Parameterliste, vor =>.

Ohne die Klammern ist (x, y) => { x, y } ein Block ohne return, und die Funktion gibt undefined zurück. Die Laufzeitregeln für Arrow Functions (kein eigenes this, kein arguments) sind dieselben wie in JavaScript; siehe Arrow Functions in JavaScript.

Wird eine Funktion inline als Argument geschrieben, annotierst du ihre Parameter meist gar nicht. TypeScript weiß aus der Funktion, an die sie übergeben wird, was der Callback bekommt (kontextuelle Typisierung): In [1, 2].map(n => n * 2) ist n bereits number. Wie man den Typ einer Funktion als Wert schreibt, (n: number) => string, steht unter Funktionstypen.

Mehrere Werte zurückgeben

Eine Funktion gibt einen Wert zurück, also gibst du ein Objekt oder ein Tupel zurück und zerlegst es per Destructuring.

Der Tupel-Rückgabetyp braucht die Annotation. Ohne sie wird [a, b] als string[] abgeleitet: Destructuring funktioniert trotzdem, aber der Typ sagt nicht mehr, dass es genau zwei Elemente sind.

async-Funktionen

Eine async-Funktion gibt immer ein Promise zurück. Annotiere den Rückgabetyp als Promise<T>, wobei T das ist, was die Funktion innen zurückgibt.

async function loadScore(id: number): Promise<number> {
  await new Promise((resolve) => setTimeout(resolve, 10));
  return id * 10;
}

async function main(): Promise<void> {
  const score = await loadScore(4); // score: number
  console.log("score", score);
}

main();

async function f(): number zu schreiben ist ein Fehler: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<number>'? (TS1064).

Der this-Parameter

JavaScript bestimmt this beim Aufruf. TypeScript lässt dich mit einem scheinbaren ersten Parameter namens this festlegen, was this sein muss. Er wird aus dem kompilierten JavaScript entfernt, und Aufrufer übergeben ihn nicht.

interface Counter {
  count: number;
}

function increment(this: Counter, by: number): void {
  this.count += by;
}

const c = { count: 0, increment };
c.increment(2); // fine: this is c

increment(2);
// error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Counter'.

Ohne den this-Parameter ist this in einer eigenständigen Funktion ein implizites any, und der Strict Mode meldet 'this' implicitly has type 'any' because it does not have a type annotation. (TS2683). In Klassenmethoden ist this bereits als Instanz der Klasse typisiert, der Parameter ist also vor allem für eigenständige Funktionen nützlich, die an Objekte gehängt werden, und für Callbacks, die Bibliotheken mit einem bestimmten this aufrufen.

Häufig gestellte Fragen

Wie gibt man in TypeScript den Rückgabetyp einer Funktion an?

Schreibe einen Doppelpunkt und den Typ hinter die Parameterliste: function total(a: number, b: number): number { ... }. Bei einer Arrow Function steht er an derselben Stelle: const total = (a: number, b: number): number => a + b;. Lässt du ihn weg, leitet TypeScript den Rückgabetyp aus den return-Anweisungen ab.

Sollte ich den Rückgabetyp in TypeScript immer annotieren?

Das ist optional, weil der Rückgabetyp abgeleitet wird. Annotiere ihn bei exportierten Funktionen und bei Funktionen mit mehreren return-Pfaden: Die Annotation dokumentiert den Vertrag, und ein falsches return wird dann in der Funktion gemeldet statt bei einem weit entfernten Aufrufer.

Was ist der Unterschied zwischen void und undefined in TypeScript?

void bedeutet: Der Aufrufer soll den Rückgabewert nicht verwenden. undefined ist ein konkreter Werttyp. Eine als (): void deklarierte Funktion darf keinen Wert zurückgeben, aber ein Callback-Typ () => void akzeptiert eine Funktion, die doch etwas zurückgibt, und das Ergebnis wird einfach ignoriert. Nimm void für Funktionen ohne Rückgabewert und undefined nur, wenn Aufrufer das Ergebnis wirklich mit undefined vergleichen.

Wie gebe ich in TypeScript mehrere Werte aus einer Funktion zurück?

Gib ein Objekt ({ min: number; max: number }) oder ein Tupel ([number, number]) zurück und zerlege es beim Aufruf per Destructuring. Objekte sind klarer, wenn die Werte unterschiedliche Bedeutungen haben; Tupel lesen sich gut bei kurzen Paaren wie [value, setValue].

Welchen Rückgabetyp hat eine async-Funktion in TypeScript?

Immer ein Promise. Eine async-Funktion, die eine number zurückgibt, hat den Rückgabetyp Promise<number>, und : number daran zu schreiben ist ein Compilerfehler (TS1064). Eine Funktion ohne Rückgabewert hat Promise<void>.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S