Praxis
Import und Export in TypeScript: Module richtig strukturieren
Wie du TypeScript-Module mit import und export organisierst. Named Exports, Default Exports, Re-Exporte und Typen-Importe verständlich erklärt.
Inhalt
Das Modulsystem ist das Rückgrat jedes TypeScript-Projekts. Wer Module sauber strukturiert, macht seinen Code wartbarer, testbarer und leichter verständlich. Dieser Ratgeber erklärt die verschiedenen Import- und Export-Varianten und zeigt, wann du welche einsetzen solltest.
Named Exports: der Standard in TypeScript
Named Exports sind die flexibelste Variante. Aus einem Modul können mehrere benannte Werte exportiert werden:
// utils/berechnung.ts
export function addieren(a: number, b: number): number {
return a + b;
}
export function multiplizieren(a: number, b: number): number {
return a * b;
}
export const PI = 3.14159;
Der Import ist präzise und zeigt sofort, was verwendet wird:
import { addieren, PI } from "./utils/berechnung";
const ergebnis = addieren(5, 3);
console.log(`Ergebnis: ${ergebnis}, Pi: ${PI}`);
TypeScript prüft beim Kompilieren, ob die importierten Namen tatsächlich existieren. Das verhindert Tippfehler, die erst zur Laufzeit auffallen würden.
Default Exports
Ein Default Export pro Modul ist möglich, aber mit Bedacht einzusetzen:
// klassen/benutzer.ts
export default class Benutzer {
constructor(
public name: string,
public email: string
) {}
gruessen(): string {
return `Hallo, ich bin ${this.name}`;
}
}
import Benutzer from "./klassen/benutzer";
const nutzer = new Benutzer("Anna", "anna@beispiel.de");
console.log(nutzer.gruessen());
Der Import-Name kann frei gewählt werden, was aber zu Inkonsistenzen führen kann. Teams sollten sich auf einheitliche Benennungen einigen.
Typen importieren und exportieren
TypeScript ermöglicht den separaten Import von Typen. Das ist besonders wichtig für Build-Tools und Tree-Shaking:
// typen/benutzer.ts
export interface Benutzer {
id: number;
name: string;
email: string;
}
export type BenutzerRolle = "admin" | "gast" | "editor";
import type { Benutzer, BenutzerRolle } from "./typen/benutzer";
function zeigeBenutzer(benutzer: Benutzer, rolle: BenutzerRolle): void {
console.log(`${benutzer.name} ist ${rolle}`);
}
Das type-Schlüsselwort im Import teilt dem Compiler mit, dass diese Importe nur für die Typprüfung benötigt werden und zur Laufzeit nicht existieren müssen. Bundler wie Vite oder esbuild können solche Importe dann effizienter verarbeiten.
Barrel-Exporte: Module bündeln
Bei größeren Projekten lohnt es sich, zusammengehörige Module über eine Indexdatei zu bündeln:
// utils/index.ts
export { addieren, multiplizieren, PI } from "./berechnung";
export { formatiereZahl } from "./formatierung";
export type { Benutzer } from "../typen/benutzer";
Der Import vereinfacht sich dann erheblich:
import { addieren, formatiereZahl } from "./utils";
Barrel-Exporte machen die Projektstruktur nach außen hin übersichtlicher und erlauben interne Umstrukturierungen ohne Änderung der Importpfade in anderen Modulen.
Namespace-Importe
Wenn du alle Exporte eines Moduls unter einem gemeinsamen Namen zusammenfassen möchtest:
import * as Berechnungen from "./utils/berechnung";
const summe = Berechnungen.addieren(10, 20);
const produkt = Berechnungen.multiplizieren(10, 20);
Namespace-Importe sind sinnvoll, wenn viele Funktionen aus einem Modul verwendet werden und Namenskonflikte vermieden werden sollen.
Dynamische Importe
Für Code-Splitting und bedingte Modul-Ladevorgänge bieten dynamische Importe die richtige Lösung:
async function ladeKomponente(name: string): Promise<void> {
if (name === "diagramm") {
const { Diagramm } = await import("./komponenten/diagramm");
const diagram = new Diagramm();
diagram.rendern();
}
}
TypeScript leitet den Typ von dynamischen Importen automatisch ab. Das Ergebnis ist ein Promise mit dem Modultyp, der alle exportierten Namen enthält.
Pfad-Aliase in tsconfig
Lange relative Importpfade lassen sich über paths in der tsconfig.json vereinfachen:
// Ohne Alias
import { Benutzer } from "../../../typen/benutzer";
// Mit Alias (nach Konfiguration)
import { Benutzer } from "@typen/benutzer";
Die Konfiguration in tsconfig.json dazu:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@typen/*": ["src/typen/*"],
"@utils/*": ["src/utils/*"]
}
}
}
Bundler wie Vite oder webpack müssen entsprechend konfiguriert werden, damit die Aliase auch zur Laufzeit aufgelöst werden.
Im Playground testen
Mit dem Playground auf dieser Seite kannst du verschiedene Import-Syntaxen direkt ausprobieren. Besonders nützlich ist das zum Verstehen, welche Exporte zur Laufzeit verfügbar sind und welche nur zur Kompilierzeit existieren.
Fazit
Ein durchdachtes Modulsystem ist die Grundlage wartbarer TypeScript-Projekte. Named Exports, Typ-Importe und Barrel-Dateien halten die Codebasis übersichtlich. Dynamische Importe ermöglichen Performance-Optimierungen. Starte mit einfachen Named Exports und erweitere das System nach Bedarf.
Häufige Fragen
Was ist der Unterschied zwischen import type und normalem import?
import type importiert ausschließlich Typen und wird zur Laufzeit vollständig entfernt. Das verbessert die Build-Performance und verhindert ungewollte Seiteneffekte beim Laden von Modulen.
Wann sollte ich Default Export statt Named Export verwenden?
Named Exports sind in den meisten Projekten vorzuziehen, da sie explizit benannt sind und Refactoring-Tools besser unterstützen. Default Exports eignen sich für Module mit einer einzigen Hauptexport-Entität, etwa React-Komponenten.
Quellen
- TypeScript Handbook: Modules (typescriptlang.org)
- Node.js Dokumentation: ECMAScript Modules
Über die Autorenschaft
Jan-Tristan Rudat
Redakteur typescript-playground.de
Themengebiet: Generationen, Kulturgeschichte, Sternzeichen, Pop-Phänomene rund ums Alter
Mehr über Jan-Tristan Rudat →Verwandte Artikel
Grundlagen
Was ist TypeScript? Eine Einführung in die typisierte JavaScript-Erweiterung
TypeScript erweitert JavaScript um statische Typen und macht große Codebases wartbarer. Lerne die Grundlagen, die Geschichte und die wichtigsten Vorteile von TypeScript.
Lesezeit 7 Min.
Grundlagen
TypeScript vs. JavaScript: Die wichtigsten Unterschiede im Überblick
TypeScript und JavaScript unterscheiden sich grundlegend in der Typprüfung, Werkzeugunterstützung und Wartbarkeit. Dieser Ratgeber erklärt die Unterschiede und hilft bei der Wahl der richtigen Sprache.
Lesezeit 8 Min.
Typen
TypeScript Typen Grundlagen: string, number, boolean und mehr
Die primitiven Typen string, number und boolean sind das Fundament von TypeScript. Dieser Ratgeber erklärt alle grundlegenden Typen mit praktischen Beispielen.
Lesezeit 9 Min.