typescript / intermediate
Snippet
Implementierung eines deklarativen Schema-Validierungswerkzeugs
Validierungsbibliotheken sind unverzichtbare Bausteine von Frameworks, da sie unstrukturierte Eingaben in typsichere Daten umwandeln. Durch bedingte Typen (`infer`) leitet TypeScript Zieltypen automatisch ab.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
type ValidationResult<T> = { success: true; data: T } | { success: false; error: string };interface Schema<T> {parse(input: unknown): ValidationResult<T>;}const stringSchema: Schema<string> = {parse(input: unknown) {return typeof input === "string"? { success: true, data: input }: { success: false, error: "Expected string" };}};const numberSchema: Schema<number> = {parse(input: unknown) {return typeof input === "number"? { success: true, data: input }: { success: false, error: "Expected number" };}};function objectSchema<T extends Record<string, Schema<any>>>(shape: T): Schema<{[K in keyof T]: T[K] extends Schema<infer U> ? U : never;}> {return {parse(input: unknown) {if (typeof input !== "object" || input === null) {return { success: false, error: "Expected object" };}const result: Record<string, any> = {};for (const key in shape) {const fieldResult = shape[key].parse((input as Record<string, any>)[key]);if (!fieldResult.success) {return { success: false, error: `Invalid key '${key}': ${fieldResult.error}` };}result[key] = fieldResult.data;}return { success: true, data: result as any };}};}const userSchema = objectSchema({ name: stringSchema, age: numberSchema });const res = userSchema.parse({ name: "Alice", age: 30 });
Erklärung
1
type ValidationResult<T> = { success: true; data: T } | { success: false; error: string };
Discriminated Union zur Darstellung erfolgreicher Validierungen oder konkreter Fehler.
2
[K in keyof T]: T[K] extends Schema<infer U> ? U : never;
Leitet aus den einzelnen Schema-Regeln den resultierenden Gesamttyp automatisch ab.
3
parse(input: unknown): ValidationResult<T>
Prüft unbekannte Eingaben (`unknown`) zur Laufzeit und stellt anschließende Typsicherheit her.