Zurück zur Startseite

PropertyDescriptors für TypeScript Schema-Validierung

Validierungsbibliothek verwendet PropertyDescriptors für typsichere Fehlerselektoren statt String-Pfaden. Unterstützt unveränderliche fluente API, Laufzeit-Introspektion und Erweiterungen. Volle Kompatibilität mit Standard Schema v1 für das Ökosystem.

Typsichere Validierung: PropertyDescriptors statt Strings
Advertisement 728x90

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.

Google AdInline article slot

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, uuid
  • number() — min, max, positive, negative, finite, multipleOf
  • boolean() — Basisvalidierung
  • date() — minDate, maxDate
  • object() — benannte Properties
  • array() — typisierte Elemente, nicht leer
  • union() — diskriminierte Unions
  • tuple() — feste Länge
  • record() — dynamische Schlüssel
  • func() — Funktions-Typisierung
  • any() — mit hasType
  • nul() — null
  • lazy() — rekursive Schemas
  • extern() — Standard Schema v1 Wrapper

Gängige Methoden auf dem Basis-SchemaBuilder:

Google AdInline article slot
  • .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:

Google AdInline article slot
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

Advertisement 728x90

Weiterlesen