TypeScript Functions - Typsichere Funktionen
Funktionen sind in TypeScript vollständig typsicher - Parameter UND Return-Werte!
Function Type Annotations
Basic Function
function add(a: number, b: number): number {
return a + b
}
const result = add(5, 3) // Type: number
Syntax:
- Parameter:
name: Type - Return Type:
: Typenach Parametern
Arrow Functions
const multiply = (a: number, b: number): number => {
return a * b
}
// One-liner
const divide = (a: number, b: number): number => a / b
Anonymous Functions
const numbers = [1, 2, 3, 4, 5]
// TypeScript erkennt context automatisch!
numbers.map(n => n * 2) // n ist number
Return Types
Expliziter Return Type
function greet(name: string): string {
return `Hello ${name}`
}
Type Inference
TypeScript erkennt Return Type automatisch:
// Return Type: string (automatisch erkannt)
function greet(name: string) {
return `Hello ${name}`
}
Empfehlung: Bei einfachen Funktionen Type Inference nutzen!
void Return Type
Für Funktionen ohne Return:
function logMessage(message: string): void {
console.log(message)
// Kein return
}
// Oder implizit
function logError(error: string) {
console.error(error)
// Return Type: void (automatisch)
}
never Return Type
Für Funktionen die NIE zurückkehren:
function throwError(message: string): never {
throw new Error(message)
// Funktion endet hier immer
}
function infiniteLoop(): never {
while (true) {
// Endlosschleife
}
}
Optional Parameters
Mit ? werden Parameter optional:
function greet(name: string, greeting?: string): string {
if (greeting) {
return `${greeting} ${name}`
}
return `Hello ${name}`
}
greet("Max") // "Hello Max"
greet("Anna", "Hi") // "Hi Anna"
Wichtig: Optionale Parameter müssen am Ende stehen!
// ❌ Falsch
function test(a?: string, b: number) {} // Error
// ✅ Richtig
function test(b: number, a?: string) {}
Default Parameters
Default-Werte machen Parameter automatisch optional:
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting} ${name}`
}
greet("Max") // "Hello Max"
greet("Anna", "Hi") // "Hi Anna"
Type Inference bei Defaults:
// greeting ist automatisch type 'string'
function greet(name: string, greeting = "Hello") {
return `${greeting} ${name}`
}
Rest Parameters
Für variable Anzahl von Parametern:
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0)
}
sum(1, 2, 3) // 6
sum(1, 2, 3, 4, 5) // 15
Mit mehreren Parametern:
function greetAll(greeting: string, ...names: string[]): void {
names.forEach(name => {
console.log(`${greeting} ${name}`)
})
}
greetAll("Hello", "Max", "Anna", "Tom")
Function Overloads
Mehrere Signaturen für eine Funktion:
// Overload Signatures
function format(value: string): string
function format(value: number): string
function format(value: boolean): string
// Implementation
function format(value: string | number | boolean): string {
if (typeof value === "string") {
return value.toUpperCase()
}
if (typeof value === "number") {
return value.toFixed(2)
}
return value ? "Yes" : "No"
}
format("hello") // "HELLO"
format(42) // "42.00"
format(true) // "Yes"
Real-World Beispiel:
function makeDate(timestamp: number): Date
function makeDate(year: number, month: number, day: number): Date
function makeDate(yearOrTimestamp: number, month?: number, day?: number): Date {
if (month !== undefined && day !== undefined) {
return new Date(yearOrTimestamp, month, day)
}
return new Date(yearOrTimestamp)
}
makeDate(1672531200000) // Date from timestamp
makeDate(2024, 0, 15) // January 15, 2024
Function Types
Funktionen als Types:
Typ für Variable
let operation: (a: number, b: number) => number
operation = (a, b) => a + b
operation = (a, b) => a * b
operation = (a, b) => a.toString() // ❌ Error: return type falsch
Type Alias für Funktion
type MathOperation = (a: number, b: number) => number
const add: MathOperation = (a, b) => a + b
const multiply: MathOperation = (a, b) => a * b
Interface für Funktion
interface Calculator {
(a: number, b: number): number
}
const add: Calculator = (a, b) => a + b
Callback Functions
Callbacks typisieren:
function fetchData(url: string, callback: (data: string) => void): void {
setTimeout(() => {
callback("Data from " + url)
}, 1000)
}
fetchData("https://api.example.com", (data) => {
console.log(data) // data ist type 'string'
})
Mit Error-Handling:
type Callback = (error: Error | null, data?: string) => void
function fetchData(url: string, callback: Callback): void {
try {
// ...
callback(null, "Success data")
} catch (error) {
callback(error as Error)
}
}
Generic Functions
Funktionen die mit verschiedenen Typen arbeiten:
function identity<T>(value: T): T {
return value
}
const num = identity(42) // Type: number
const str = identity("Hello") // Type: string
Array-Beispiel:
function firstElement<T>(arr: T[]): T | undefined {
return arr[0]
}
const first = firstElement([1, 2, 3]) // Type: number | undefined
const firstStr = firstElement(["a", "b"]) // Type: string | undefined
Mit Constraints:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key]
}
const person = { name: "Max", age: 25 }
const name = getProperty(person, "name") // Type: string
const age = getProperty(person, "age") // Type: number
// Generic Function mit Constraints, Default Parameter, Rest Parameters
function processItems<T extends { id: number }>(
processor: (item: T) => void,
...items: T[]
): number {
items.forEach(processor)
return items.length
}
interface Product {
id: number
name: string
price: number
}
const products: Product[] = [
{ id: 1, name: "Laptop", price: 999 },
{ id: 2, name: "Mouse", price: 29 }
]
const count = processItems(
(product) => console.log(product.name),
...products
)
// count: 2
// Console: "Laptop", "Mouse"📝 Quiz
Was ist der Unterschied zwischen void und never als Return Type?
Tipps & Tricks
Return Type Annotations wann nötig?
// ✅ Type Inference reicht
function add(a: number, b: number) {
return a + b // Return type: number (erkannt)
}
// ✅ Explizit bei komplexen Returns
function processData(data: any) {
if (typeof data === "string") {
return data.toUpperCase()
}
if (typeof data === "number") {
return data.toFixed(2)
}
return data
}
// Besser mit explizitem Return Type
// ✅ Explizit bei Public APIs
export function calculate(x: number): number {
// Return Type Teil der API
}
Destructuring mit Types
// Parameter Destructuring
interface User {
name: string
age: number
}
function greet({ name, age }: User): string {
return `${name} is ${age} years old`
}
// Array Destructuring
function getCoordinates(): [number, number] {
return [10, 20]
}
const [x, y] = getCoordinates()
this Parameter Type
interface User {
name: string
greet(this: User): void
}
const user: User = {
name: "Max",
greet() {
console.log(`Hello ${this.name}`)
}
}
const greetFn = user.greet
greetFn() // ❌ Error: 'this' context required
user.greet() // ✅ OK
Häufige Fehler
Fehler 1: Optionale Parameter vor Required
❌ FALSCH:
function test(optional?: string, required: number) {
// ...
}
✅ RICHTIG:
function test(required: number, optional?: string) {
// ...
}
Fehler 2: Return Type vergessen bei komplexen Funktionen
❌ FALSCH:
function getData(id: number) {
if (id < 0) return null
if (id === 0) return undefined
return { id, name: "Item" }
}
// Return Type: null | undefined | { id: number; name: string }
// Unklar für Nutzer!
✅ RICHTIG:
function getData(id: number): { id: number; name: string } | null {
if (id <= 0) return null
return { id, name: "Item" }
}
Fehler 3: Function Overloads falsch ordnen
❌ FALSCH:
function process(value: any): any // Zu general
function process(value: string): string
function process(value: number): number
function process(value: any): any {
return value
}
✅ RICHTIG:
// Spezifische Overloads ZUERST
function process(value: string): string
function process(value: number): number
function process(value: string | number): string | number {
return value
}
Zusammenfassung
Du hast gelernt:
- ✅ Parameter und Return Types typisieren
- ✅ Optional Parameters mit
? - ✅ Default Parameters für Standardwerte
- ✅ Rest Parameters mit
... - ✅ Function Overloads für mehrere Signaturen
- ✅ Generics für flexible Funktionen
- ✅ void vs never Return Types
Key Takeaways:
- Type Inference bei einfachen Funktionen nutzen
- Optionale Parameter immer am Ende
- Function Overloads: spezifische zuerst
- Generics für wiederverwendbare Funktionen
- Callbacks immer typisieren
Nächste Schritte
Als Nächstes lernst du:
- Classes in TypeScript
- Generics im Detail
- Advanced Types
- Utility Types
Viel Erfolg! 🚀
Gut gemacht! 🎉
Du hast "TypeScript Functions - Typsichere Funktionen" abgeschlossen
Artikel bewerten
Bitte einloggen um zu bewerten
Das könnte dich auch interessieren
TypeScript Basic Types - Primitive Datentypen
Lerne die grundlegenden Datentypen in TypeScript kennen: string, number, boolean, arrays, tuples und mehr.
TypeScript Best Practices - Professioneller Code
Lerne die wichtigsten Best Practices für sauberen und wartbaren TypeScript Code. Naming, Patterns, Do's and Don'ts.
TypeScript Classes - Objektorientierte Programmierung
Lerne Classes in TypeScript mit Access Modifiers, Constructors, Inheritance, Abstract Classes und mehr.