Zpět na domů

PropertyDescriptors pro validaci schémat TypeScript

Knihovna validace používá PropertyDescriptors pro type-safe selektory chyb místo řetězcových cest. Podporuje immutabilní fluent API, runtime-introspekci a rozšíření. Plná kompatibilita se Standard Schema v1 pro ekosystém.

Type-safe validace: PropertyDescriptors místo řetězců
Advertisement 728x90

PropertyDescriptors při validaci schémat: type-safe přístup k chybám

Vývojáři se často potýkají s validací složitých vnořených objektů v JavaScript projektech. Standardní přístupy s řetězcovými cestami pro získání chyb vedou k runtime chybám při refaktoringu. Alternativa jsou PropertyDescriptors: strukturovaný strom deskriptorů vlastností, který zajišťuje type-safe selektory s autokompletací v IDE.

Klíčový princip – každé schéma vytváří strom uzlů, kde každý deskriptor zná cestu k vlastnosti, přidružené schéma, rodiče a metody přístupu. To umožňuje kompilovat selektory přes lambdy místo řetězců.

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('Město je povinné'),
            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);

Při přejmenování pole TypeScript vyhodí chybu kompilace, IDE zajistí autokompletaci.

Google AdInline article slot

Imutabilní fluent API a buildery

Všechny volání metod na schématech vracejí nové instance, čímž se vylučují mutace. To usnadňuje kompozici a opětovné použití.

Knihovna obsahuje 14 typů builderů:

  • string() — minLength, maxLength, matches, email, url, uuid
  • number() — min, max, positive, negative, finite, multipleOf
  • boolean() — základní validace
  • date() — minDate, maxDate
  • object() — pojmenované vlastnosti
  • array() — typizované prvky, nonempty
  • union() — diskrimminované unie
  • tuple() — pevné délky
  • record() — dynamické klíče
  • func() — typizace funkcí
  • any() — s hasType
  • null() — null
  • lazy() — rekurzivní schémata
  • extern() — obal Standard Schema v1

Společné metody základního SchemaBuilder:

Google AdInline article slot
  • .optional() — přijímá undefined
  • .required('msg') — povinné pole
  • .nullable() — přijímá null
  • .default(value) — výchozí hodnota
  • .catch(value) — při chybě
  • .readonly() — Readonly<T>
  • .brand<'T'>() — branded types
  • .describe('text') — zachování JSDoc
  • .addValidator(fn) — vlastní logika
  • .addPreprocessor(fn) — předzpracování
  • .introspect() — metadata

Runtime introspekce schémat

Metoda .introspect() vrací úplný popis schématu: typ, omezení, příznaky, popisy, rozšíření. Data jsou dostupná za běhu pro nástroje.

const Name = string().minLength(2).maxLength(100).describe('Jméno uživatele').optional();

const info = Name.introspect();
// info.type === 'string'
// info.minLength === 2
// info.description === 'Jméno uživatele'

Introspekce je rozšířena pro každý builder. Používá se pro konverzi do JSON Schema, generování formulářů, vlastních rendererů.

Systém typizovaných rozšíření

Rozšíření jsou kompozitní, introspektovatelná doplnění jádra. Příklad HEX barvy a portu:

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: 'Musí být HEX barva' }]
                };
            });
        }
    }
});

const s = withExtensions(hexColorExt, portExt);
const colorSchema = s.string().hexColor();

Rozšíření jsou vidět v .introspect().extensions. Vestavěné: email, url, uuid, positive, nonempty.

Kompatibilita se Standard Schema v1

Schémata implementují Standard Schema v1 pro integraci s tRPC, TanStack Form, React Hook Form, Hono. extern() obaluje Zod/Valibot do builderu.

const UserSchema = object({
    name: string().minLength(2),
    address: extern(zodAddress)
});

PropertyDescriptors zajišťují type-safe přístup k chybám i ve smíšených schématech.

Co je důležité

  • Type-safe selektory přes PropertyDescriptors eliminují řetězcové cesty a runtime chyby.
  • Imutabilita fluent API usnadňuje kompozici bez mutací.
  • Runtime introspekce umožňuje extrakci metadat pro nástroje.
  • Rozšíření — typizovaná, kompozitní doplnění jádra.
  • Standard Schema v1 zajišťuje kompatibilitu s ekosystémem.

— Editorial Team

Advertisement 728x90

Číst dál