Pureline TypeScript
Starke Grenzen, inferierte Interna.
Pureline TypeScript erbt alle Regeln von Pureline JavaScript. Dazu kommt ein klares Typ-Modell: explizite Typen an API-Grenzen, Inferenz im Inneren, unknown statt any und Unions statt Zeremonie.
Erbt alle Regeln von Pureline JavaScript.
Profilregeln
any vermeiden
any schaltet das Typsystem ab. Wirklich unbekannte Daten sind unknown und werden an der Grenze validiert.
function load(value: any): any {
} const config = JSON.parse(raw) as unknown as Config; function load(value: UserId): User {
} function parse(input: unknown): Config {
} Typen bewusst einsetzen
Inferierte und explizite lokale Typen sind beide Pureline-konform. Eine Annotation ist nicht redundant, nur weil TypeScript den Typ auch inferieren könnte.
Explizite Typen lohnen sich besonders, wenn sie die Absicht klarer machen, einen erwarteten Vertrag dokumentieren, eine Grenze vor ungewollter Verbreiterung schützen, das Refactoring absichern oder Code verständlich machen, ohne die ganze Aufrufkette zu verfolgen.
Inferenz soll Lärm entfernen. Sie ist nie eine Regel gegen das Typsystem.
let state = "idle";
// state ist jetzt string, jeder Tippfehler kompiliert
state = "redy"; const user = loadUser(); const user: User = loadUser(); let state: SessionState = "idle"; Kein I-Prefix
Das I-Prefix ist eine reine Java-Konvention von Pureline. TypeScript-Interfaces heißen nach ihrer Rolle. Das Prefix ist profilspezifisch: Java und Emvus verwenden es, TypeScript nicht.
interface ISession {
} interface Session {
} interface vs. type
interface für objektartige Verträge. type für Unions, Aliase und Funktionssignaturen.
type User = {
id: string;
name: string;
}; interface Handler {
(packet: Packet): Promise<void>;
} interface User {
id: string;
name: string;
} type SessionState = "ready" | "closed" | "failed"; type Handler = (packet: Packet) => Promise<void>; Union Types statt Enums
Ein enum nur dann, wenn das Konstrukt echten Mehrwert liefert. Für einfache Zustände ist ein Union Type klarer.
enum State {
Idle = "idle",
Ready = "ready",
Closed = "closed"
} type State = "idle" | "ready" | "closed"; Starke Typen an Grenzen, Freiheit im Inneren
Öffentliche APIs, externe Daten, Persistenzgrenzen und Netzwerk-Payloads zeigen normalerweise klare Typen.
Innerhalb einer Implementierung sind explizite Annotationen und Inferenz gleichermaßen gültig. Gewählt wird die Form, die den Code am leichtesten verständlich macht. Weniger Annotationen gelten nicht automatisch als sauberer.
export async function openSession(request, options) {
const payload = await fetch(url).then(response => response.json());
return sessions.create(payload);
} export async function openSession(request: Request): Promise<Session | null> {
const user = await users.load(request.userId);
if (!user) {
return null;
}
return sessions.create(user);
} Folder Density
Ein TypeScript-Feature- oder Quellordner enthält standardmäßig höchstens **10 produktive Source-Module**.
Barrel-Dateien wie index.ts, reine Deklarationsdateien, Tests, generierte Dateien und reine Metadaten-Dateien zählen nicht mit.
Eine Aufteilung bildet eine echte Verantwortungsgrenze ab.
session/
session/state/
session/transport/
session/storage/ Core-Regeln im TypeScript-Checker
Zusätzlich zu den Profilregeln prüft der Checker für TypeScript diese Regeln aus dem Pureline Core: