Fortgeschritten132025-01-15

TypeScript Functions - Typsichere Funktionen

Lerne wie du Funktionen in TypeScript typisierst. Parameter, Return Types, Optional Parameters, Rest Parameters und mehr.

#typescript#functions#parameters#return-types

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: : Type nach 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
Komplette Funktion mit allen Features
// 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! 🚀

TypeScriptLektion 4 von 15
27% abgeschlossen
Lektion abgeschlossen!

Gut gemacht! 🎉

Du hast "TypeScript Functions - Typsichere Funktionen" abgeschlossen

Artikel bewerten

0.0 (0 Bewertungen)

Bitte einloggen um zu bewerten