Property-Deskriptoren für Schema-Validierung: Typsichere Fehlerbehandlung in TypeScript
Entwickler kämpfen häufig mit der Validierung komplexer verschachtelter Objekte in JavaScript-Projekten. Traditionelle Ansätze mit String-Pfaden zur Fehlerauslesung führen bei Refactorings zu Laufzeitfehlern. Die Lösung? Property-Deskriptoren: Ein strukturierter Baum von Property-Deskriptoren, der typsichere Selektoren mit vollständiger IDE-Autovervollständigung bietet.
Die Kernidee ist, dass jedes Schema einen Baum von Knoten aufbaut, wobei jeder Deskriptor seinen Property-Pfad, verknüpftes Schema, Elternknoten und Zugriffsmethoden kennt. So können Selektoren über Lambdas statt bruchbarer Strings kompiliert werden.
import { object, string, number, InferType } from '@cleverbrush/schema';
const OrderSchema = object({
id: string(),
customer: object({
name: string().minLength(2),
email: string().email(),
address: object({
city: string().required('Stadt ist erforderlich'),
zip: number()
})
}),
total: number().min(0)
});
const result = OrderSchema.validate({
id: '123',
customer: {
name: 'A',
email: 'not-an-email',
address: {
zip: -1
}
},
total: -5
});
const nameErrors = result.getErrorsFor(t => t.customer.name);
const cityErrors = result.getErrorsFor(t => t.customer.address.city);
Ein Feld umbenennen? TypeScript fängt es zur Kompilierzeit ab. Ihre IDE bietet volle Autovervollständigung.
Unveränderliche Fluent-API und Builder
Alle Schema-Methodenaufrufe geben neue Instanzen zurück und verhindern Mutationen. Das macht Komposition und Wiederverwendung kinderleicht.
Die Bibliothek bietet 14 Builder-Typen:
string()— minLength, maxLength, matches, email, url, uuidnumber()— min, max, positive, negative, finite, multipleOfboolean()— Basisvalidierungdate()— minDate, maxDateobject()— benannte Propertiesarray()— typisierte Elemente, nicht leerunion()— diskriminierte Unionstuple()— feste Längerecord()— dynamische Schlüsselfunc()— Funktions-Typisierungany()— mit hasTypenul()— nulllazy()— rekursive Schemasextern()— Standard Schema v1 Wrapper
Gängige Methoden auf dem Basis-SchemaBuilder:
.optional()— akzeptiert undefined.required('msg')— Pflichtfeld.nullable()— akzeptiert null.default(value)— Standardwert.catch(value)— Fallback bei Fehler.readonly()— Readonly<T>.brand<'T'>()— gebrandete Typen.describe('text')— JSDoc-Erhaltung.addValidator(fn)— benutzerdefinierte Logik.addPreprocessor(fn)— Vorverarbeitung.introspect()— Metadaten
Laufzeit-Schema-Introspektion
Die Methode .introspect() liefert eine vollständige Schema-Beschreibung: Typ, Einschränkungen, Flags, Beschreibungen, Erweiterungen. Alles zur Laufzeit für Tools und Integrationen verfügbar.
const Name = string().minLength(2).maxLength(100).describe('Benutzername').optional();
const info = Name.introspect();
// info.type === 'string'
// info.minLength === 2
// info.description === 'Benutzername'
Introspektion ist für jeden Builder vollständig ausgeführt. Ideal für JSON-Schema-Konvertierung, Formulargenerierung oder eigene Renderer.
Typsicheres Erweiterungssystem
Erweiterungen sind komponierbare, introspektierbare Add-ons zum Kern. Beispiel für HEX-Farben und Ports:
const hexColorExt = defineExtension({
string: {
hexColor(this: StringSchemaBuilder) {
return this.addValidator((v) => {
const valid = /^#[0-9a-f]{6}$/i.test(v as string);
return {
valid,
errors: valid ? [] : [{ message: 'Muss gültige HEX-Farbe sein' }]
};
});
}
}
});
const s = withExtensions(hexColorExt, portExt);
const colorSchema = s.string().hexColor();
Erweiterungen erscheinen in .introspect().extensions. Eingebaut: email, url, uuid, positive, nicht leer.
Kompatibilität mit Standard Schema v1
Schemata implementieren Standard Schema v1 für nahtlose Integration mit tRPC, TanStack Form, React Hook Form, Hono. extern() wrappt Zod/Valibot in Builder.
const UserSchema = object({
name: string().minLength(2),
address: extern(zodAddress)
});
Property-Deskriptoren sorgen für typsicheren Fehlerzugriff auch in gemischten Schemata.
Wichtige Erkenntnisse
- Typsichere Selektoren über Property-Deskriptoren eliminieren String-Pfade und Laufzeitfehler.
- Unveränderliche Fluent-API vereinfacht Komposition ohne Nebenwirkungen.
- Laufzeit-Introspektion extrahiert Metadaten für jedes Tool.
- Erweiterungen — typsichere, komponierbare Kern-Add-ons.
- Standard Schema v1 gewährleistet Ökosystem-Kompatibilität.
— Editorial Team
Noch keine Kommentare.