Elysia Tools

Durchsuche Tools, Beispiele, visuelle Erklärungen und Themenguides an einem klaren Ort.

Beliebte Kategorien

Themen

Sprache
ZHESPTRUFRDEEN

Elysia Tools

Mobile Navigation

Validierungsbibliotheken

Zod Schema-Validierung

Zod TypeScript-erste Schema-Validierungs-Beispiele einschließlich Primitiven, Objekten, Arrays, Transformationen, benutzerdefinierten Validatoren und Fehlerbehandlung

Beispiele

Einträge in dieser Sammlung

QuellcodetypescriptEinfach

Zod Grundlagen und Primitive

Grundlegende Zod Schema-Validierung mit primitiven Typen, Basis-Validierung und einfachen Transformationen

Schwierigkeit

3/10

Geschätzte Zeit

25 min

Schlagwörter

zod, validation, typescript, runtime

Voraussetzungen

TypeScript basics, JavaScript

typescript
// Zod Basics and Primitive Types Example

import { z } from 'zod';

// 1. Primitive Types
const stringSchema = z.string();
const numberSchema = z.number();
const booleanSchema = z.boolean();
const dateSchema = z.date();
const undefinedSchema = z.undefined();
const nullSchema = z.null();

// Test primitive validation
console.log(stringSchema.parse('hello')); // ✅ 'hello'
console.log(numberSchema.parse(42)); // ✅ 42
console.log(booleanSchema.parse(true)); // ✅ true
console.log(dateSchema.parse(new Date())); // ✅ Date object
console.log(undefinedSchema.parse(undefined)); // ✅ undefined
console.log(nullSchema.parse(null)); // ✅ null

// 2. Type Constraints
const minStringLength = z.string().min(5);
const maxStringLength = z.string().max(10);
const emailRegex = z.string().email();
const urlRegex = z.string().url();

console.log(minStringLength.parse('hello world')); // ✅
console.log(maxStringLength.parse('short')); // ✅
console.log(emailRegex.parse('[email protected]')); // ✅
console.log(urlRegex.parse('https://example.com')); // ✅

// 3. Number Constraints
const positiveNumber = z.number().positive();
const nonNegativeNumber = z.number().nonnegative();
const maxNumber = z.number().max(100);
const minNumber = z.number().min(18);
const intNumber = z.number().int();

console.log(positiveNumber.parse(10)); // ✅
console.log(nonNegativeNumber.parse(0)); // ✅
console.log(maxNumber.parse(50)); // ✅
console.log(minNumber.parse(25)); // ✅
console.log(intNumber.parse(42)); // ✅

// 4. Optional and Nullable Types
const optionalString = z.string().optional();
const nullableString = z.string().nullable();
const optionalOrNullableString = z.string().optional().nullable();

console.log(optionalString.parse('hello')); // ✅ 'hello'
console.log(optionalString.parse(undefined)); // ✅ undefined
console.log(nullableString.parse(null)); // ✅ null
console.log(nullableString.parse('hello')); // ✅ 'hello'

// 5. Default Values
const stringWithDefault = z.string().default('default value');
const optionalStringWithDefault = z.string().optional().default('optional default');

console.log(stringWithDefault.parse(undefined)); // ✅ 'default value'
console.log(optionalStringWithDefault.parse(undefined)); // ✅ 'optional default'

// 6. Enum-like Values
const directionSchema = z.enum(['north', 'south', 'east', 'west']);
const brandSchema = z.enum(['Nike', 'Adidas', 'Puma', 'Reebok']);

console.log(directionSchema.parse('north')); // ✅ 'north'
console.log(brandSchema.parse('Nike')); // ✅ 'Nike'

// 7. Literal Types
const trueSchema = z.literal(true);
const numberLiteral = z.literal(42);
const stringLiteral = z.literal('specific-value');

console.log(trueSchema.parse(true)); // ✅ true
console.log(numberLiteral.parse(42)); // ✅ 42
console.log(stringLiteral.parse('specific-value')); // ✅ 'specific-value'

// 8. Union Types
const stringOrNumber = z.union([z.string(), z.number()]);
const colorSchema = z.union([z.literal('red'), z.literal('green'), z.literal('blue')]);

console.log(stringOrNumber.parse('hello')); // ✅ 'hello'
console.log(stringOrNumber.parse(42)); // ✅ 42
console.log(colorSchema.parse('red')); // ✅ 'red'

// 9. Intersection Types
const personName = z.object({
  firstName: z.string(),
  lastName: z.string(),
});

const personAge = z.object({
  age: z.number().positive(),
});

const personWithDetails = z.intersection(personName, personAge);

console.log(personWithDetails.parse({
  firstName: 'John',
  lastName: 'Doe',
  age: 30
})); // ✅

// 10. Safe Parsing
const result = stringSchema.safeParse(123);
if (result.success) {
  console.log('Valid:', result.data);
} else {
  console.log('Invalid:', result.error);
}

// 11. Custom Validation
const customEmailSchema = z.string().email().refine((email) => {
  return email.endsWith('@company.com');
}, {
  message: 'Email must be from @company.com domain',
  path: ['domain']
});

try {
  customEmailSchema.parse('[email protected]'); // ✅
  customEmailSchema.parse('[email protected]'); // ❌
} catch (error) {
  console.error('Custom validation error:', error);
}

// 12. Transformations
const stringToNumber = z.string().transform((str) => parseInt(str, 10));
const uppercaseString = z.string().transform((str) => str.toUpperCase());
const trimmedString = z.string().transform((str) => str.trim());

const transformedNumber = stringToNumber.parse('123'); // ✅ 123 (number)
const transformedUpper = uppercaseString.parse('hello'); // ✅ 'HELLO'
const transformedTrim = trimmedString.parse('  hello  '); // ✅ 'hello'

// 13. Preprocessing and Postprocessing
const preprocessSchema = z.string().transform((str) => str.trim().toLowerCase());

const postprocessSchema = z.string().transform((str) => {
  return {
    original: str,
    length: str.length,
    uppercase: str.toUpperCase()
  };
});

const preprocessResult = preprocessSchema.parse('  HELLO  '); // ✅ 'hello'
const postprocessResult = postprocessSchema.parse('hello'); // ✅ { original: 'hello', length: 5, uppercase: 'HELLO' }

// 14. Pipeline Transformations
const dateToTimestamp = z.date().transform((date) => date.getTime());
const timestampToDate = z.number().transform((timestamp) => new Date(timestamp));

const timestamp = dateToTimestamp.parse(new Date()); // ✅ timestamp (number)
const date = timestampToDate.parse(Date.now()); // ✅ Date object

// 15. Error Customization
const customErrorSchema = z.string({
  errorMap: (issue, ctx) => {
    if (issue.code === z.ZodIssueCode.invalid_string) {
      return { message: 'Custom error message for invalid string' };
    }
    if (issue.code === z.ZodIssueCode.too_small) {
      return { message: 'String is too short!' };
    }
    return { message: ctx.defaultError };
  },
}).min(5);

try {
  customErrorSchema.parse('abc'); // ❌ Custom error
} catch (error) {
  console.log('Custom error message');
}

// 16. Advanced Primitive Examples

// Password validation with multiple requirements
const passwordSchema = z.string()
  .min(8, 'Password must be at least 8 characters')
  .max(100, 'Password must be less than 100 characters')
  .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
  .regex(/[a-z]/, 'Password must contain at least one lowercase letter')
  .regex(/[0-9]/, 'Password must contain at least one number')
  .regex(/[^A-Za-z0-9]/, 'Password must contain at least one special character');

// Username validation
const usernameSchema = z.string()
  .min(3, 'Username must be at least 3 characters')
  .max(20, 'Username must be less than 20 characters')
  .regex(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers, and underscores')
  .refine((username) => !username.startsWith('_'), {
    message: 'Username cannot start with an underscore'
  })
  .refine((username) => !username.endsWith('_'), {
    message: 'Username cannot end with an underscore'
  });

// Phone number validation
const phoneNumberSchema = z.string()
  .regex(/^+?[1-9]d{1,14}$/, 'Invalid phone number format')
  .transform((phone) => {
    // Normalize phone number format
    return phone.replace(/[^0-9+]/g, '');
  });

// URL validation with protocols
const urlSchema = z.string().url().refine((url) => {
  const protocols = ['http:', 'https:', 'ftp:'];
  try {
    const parsedUrl = new URL(url);
    return protocols.includes(parsedUrl.protocol);
  } catch {
    return false;
  }
}, {
  message: 'URL must use http, https, or ftp protocol'
});

// Color validation
const colorHexSchema = z.string()
  .regex(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/, 'Invalid hex color format')
  .transform((hex) => hex.toLowerCase());

const colorRgbSchema = z.string()
  .regex(/^rgb(s*d+s*,s*d+s*,s*d+s*)$/i, 'Invalid RGB format')
  .transform((rgb) => {
    const matches = rgb.match(/d+/g);
    if (!matches || matches.length !== 3) return null;
    return {
      r: parseInt(matches[0]),
      g: parseInt(matches[1]),
      b: parseInt(matches[2])
    };
  });

// Test advanced validation
try {
  passwordSchema.parse('MySecureP@ssw0rd!'); // ✅
  usernameSchema.parse('john_doe123'); // ✅
  phoneNumberSchema.parse('+1-555-123-4567'); // ✅
  urlSchema.parse('https://example.com'); // ✅
  colorHexSchema.parse('#FF5733'); // ✅
  colorRgbSchema.parse('rgb(255, 87, 51)'); // ✅
} catch (error) {
  console.error('Advanced validation error:', error);
}

// 17. Usage Examples

// Form validation function
function validateUserInput(userData: unknown) {
  const userSchema = z.object({
    name: z.string().min(2).max(50),
    email: z.string().email(),
    age: z.number().min(18).max(120),
    website: z.string().url().optional(),
    bio: z.string().max(500).optional()
  });

  const result = userSchema.safeParse(userData);

  if (result.success) {
    return { success: true, data: result.data };
  } else {
    return {
      success: false,
      errors: result.error.issues.map(issue => ({
        field: issue.path.join('.'),
        message: issue.message
      }))
    };
  }
}

// API response validation
function validateApiResponse(response: unknown) {
  const responseSchema = z.object({
    success: z.boolean(),
    data: z.unknown().optional(),
    error: z.string().optional(),
    timestamp: z.string()
  });

  return responseSchema.parse(response);
}

// Environment variable validation
function validateEnvVars(envVars: Record<string, unknown>) {
  const envSchema = z.object({
    NODE_ENV: z.enum(['development', 'production', 'test']),
    PORT: z.string().transform(Number).pipe(z.number().positive()),
    DATABASE_URL: z.string().url(),
    JWT_SECRET: z.string().min(32),
    API_KEY: z.string().min(16),
    ENABLE_LOGGING: z.string().transform(Boolean).pipe(z.boolean()).default(true),
    MAX_CONNECTIONS: z.string().transform(Number).pipe(z.number().positive()).default(10)
  });

  return envSchema.parse(envVars);
}

// Example usage
console.log('\n--- Usage Examples ---');

const userInput = {
  name: 'John Doe',
  email: '[email protected]',
  age: 25,
  website: 'https://johndoe.com',
  bio: 'Software developer'
};

const userValidation = validateUserInput(userInput);
console.log('User validation:', userValidation);

const apiResponse = {
  success: true,
  data: { message: 'Hello World' },
  timestamp: new Date().toISOString()
};

const validatedResponse = validateApiResponse(apiResponse);
console.log('API response validation:', validatedResponse);

const envVars = {
  NODE_ENV: 'development',
  PORT: '3000',
  DATABASE_URL: 'https://localhost:5432/mydb',
  JWT_SECRET: 'my-super-secret-jwt-key-32-chars-long',
  API_KEY: 'my-api-key-16-chars'
};

const validatedEnv = validateEnvVars(envVars);
console.log('Environment validation:', validatedEnv);

export {
  stringSchema,
  numberSchema,
  booleanSchema,
  dateSchema,
  userSchema: z.object({
    name: z.string().min(2).max(50),
    email: z.string().email(),
    age: z.number().min(18).max(120),
    website: z.string().url().optional(),
    bio: z.string().max(500).optional()
  }),
  passwordSchema,
  usernameSchema,
  validateUserInput,
  validateApiResponse,
  validateEnvVars
};
QuellcodetypescriptMittel

Zod Objekte und Arrays

Komplexe Zod Schemas für Objekte, Arrays, verschachtelte Strukturen und fortgeschrittene Validierungs-Muster

Schwierigkeit

6/10

Geschätzte Zeit

40 min

Schlagwörter

zod, validation, typescript, schemas, objects

Voraussetzungen

Zod basics, TypeScript, Advanced data structures

typescript
// Zod Objects and Arrays Example

import { z } from 'zod';

// 1. Basic Object Schema
const userSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(2).max(50),
  email: z.string().email(),
  age: z.number().min(13).max(120),
  isActive: z.boolean().default(true),
  createdAt: z.date().default(new Date()),
});

type User = z.infer<typeof userSchema>;

const validUser = {
  id: '550e8400-e29b-41d4-a716-446655440000',
  name: 'John Doe',
  email: '[email protected]',
  age: 30,
  isActive: true,
  createdAt: new Date()
};

console.log(userSchema.parse(validUser)); // ✅

// 2. Partial Object (for updates)
const updateUserSchema = userSchema.partial();

const updateData = {
  name: 'Jane Doe',
  age: 28
};

console.log(updateUserSchema.parse(updateData)); // ✅

// 3. Required Object (no optional/extra properties)
const strictUserSchema = z.object({
  name: z.string(),
  email: z.string().email()
}).strict();

console.log(strictUserSchema.parse({ name: 'John', email: '[email protected]' })); // ✅
// strictUserSchema.parse({ name: 'John', email: '[email protected]', extra: 'value' }); // ❌

// 4. Object with Passthrough (allow extra properties)
const passthroughUserSchema = z.object({
  name: z.string(),
  email: z.string().email()
}).passthrough();

console.log(passthroughUserSchema.parse({
  name: 'John',
  email: '[email protected]',
  role: 'admin',
  department: 'IT'
})); // ✅, preserves extra properties

// 5. Object with Catchall (custom handling for extra properties)
const catchallUserSchema = z.object({
  name: z.string(),
  email: z.string().email()
}).catchall(z.string());

console.log(catchallUserSchema.parse({
  name: 'John',
  email: '[email protected]',
  role: 'admin', // ✅, string value
  score: 100 // ❌, not a string
}));

// 6. Array Schemas
const stringArraySchema = z.array(z.string());
const numberArraySchema = z.array(z.number());
const userArraySchema = z.array(userSchema);

console.log(stringArraySchema.parse(['hello', 'world'])); // ✅
console.log(numberArraySchema.parse([1, 2, 3])); // ✅
console.log(userArraySchema.parse([validUser, validUser])); // ✅

// 7. Array Constraints
const minLengthArray = z.array(z.string()).min(2);
const maxLengthArray = z.array(z.number()).max(5);
const exactLengthArray = z.array(z.string()).length(3);

console.log(minLengthArray.parse(['a', 'b', 'c'])); // ✅
console.log(maxLengthArray.parse([1, 2, 3])); // ✅
console.log(exactLengthArray.parse(['x', 'y', 'z'])); // ✅

// 8. Non-empty Array
const nonEmptyArray = z.array(z.string()).nonempty();
console.log(nonEmptyArray.parse(['hello'])); // ✅
// nonEmptyArray.parse([]); // ❌

// 9. Set-like Array (unique values)
const uniqueArray = z.array(z.string()).refine(
  (arr) => new Set(arr).size === arr.length,
  { message: 'Array must contain unique values' }
);

console.log(uniqueArray.parse(['a', 'b', 'c'])); // ✅
// uniqueArray.parse(['a', 'b', 'a']); // ❌

// 10. Nested Objects
const addressSchema = z.object({
  street: z.string(),
  city: z.string(),
  state: z.string().length(2),
  zipCode: z.string().regex(/^d{5}(-d{4})?$/),
  country: z.string().default('USA'),
  coordinates: z.object({
    lat: z.number().min(-90).max(90),
    lng: z.number().min(-180).max(180)
  }).optional()
});

const userWithAddressSchema = z.object({
  id: z.string().uuid(),
  name: z.string(),
  email: z.string().email(),
  address: addressSchema,
  phoneNumbers: z.array(z.string().regex(/^+?[1-9]d{1,14}$/)).optional(),
  metadata: z.record(z.unknown()).optional()
});

const userWithAddress = {
  id: '550e8400-e29b-41d4-a716-446655440000',
  name: 'John Doe',
  email: '[email protected]',
  address: {
    street: '123 Main St',
    city: 'New York',
    state: 'NY',
    zipCode: '10001',
    coordinates: { lat: 40.7128, lng: -74.0060 }
  },
  phoneNumbers: ['+1-555-123-4567'],
  metadata: {
    lastLogin: new Date().toISOString(),
    preferences: { theme: 'dark' }
  }
};

console.log(userWithAddressSchema.parse(userWithAddress)); // ✅

// 11. Array of Objects
const postSchema = z.object({
  id: z.string().uuid(),
  title: z.string().min(1).max(200),
  content: z.string().max(10000),
  authorId: z.string().uuid(),
  tags: z.array(z.string().min(1).max(20)).max(5),
  published: z.boolean().default(false),
  createdAt: z.date(),
  updatedAt: z.date().optional()
});

const postsSchema = z.array(postSchema);

const posts = [
  {
    id: '550e8400-e29b-41d4-a716-446655440001',
    title: 'Hello World',
    content: 'This is my first post',
    authorId: '550e8400-e29b-41d4-a716-446655440000',
    tags: ['intro', 'hello'],
    published: true,
    createdAt: new Date()
  },
  {
    id: '550e8400-e29b-41d4-a716-446655440002',
    title: 'Second Post',
    content: 'Another interesting post',
    authorId: '550e8400-e29b-41d4-a716-446655440000',
    tags: ['updates', 'announcement'],
    published: false,
    createdAt: new Date()
  }
];

console.log(postsSchema.parse(posts)); // ✅

// 12. Discriminated Unions
const baseEventSchema = z.object({
  id: z.string().uuid(),
  timestamp: z.date(),
  userId: z.string().uuid()
});

const userLoginEventSchema = baseEventSchema.extend({
  type: z.literal('user.login'),
  ipAddress: z.string().ip(),
  userAgent: z.string()
});

const userLogoutEventSchema = baseEventSchema.extend({
  type: z.literal('user.logout'),
  sessionDuration: z.number().positive()
});

const postCreatedEventSchema = baseEventSchema.extend({
  type: z.literal('post.created'),
  postId: z.string().uuid(),
  postTitle: z.string()
});

const eventSchema = z.discriminatedUnion('type', [
  userLoginEventSchema,
  userLogoutEventSchema,
  postCreatedEventSchema
]);

type Event = z.infer<typeof eventSchema>;

// Valid events
const loginEvent = {
  id: '550e8400-e29b-41d4-a716-446655440003',
  timestamp: new Date(),
  userId: '550e8400-e29b-41d4-a716-446655440000',
  type: 'user.login' as const,
  ipAddress: '192.168.1.1',
  userAgent: 'Mozilla/5.0...'
};

const logoutEvent = {
  id: '550e8400-e29b-41d4-a716-446655440004',
  timestamp: new Date(),
  userId: '550e8400-e29b-41d4-a716-446655440000',
  type: 'user.logout' as const,
  sessionDuration: 3600
};

const postEvent = {
  id: '550e8400-e29b-41d4-a716-446655440005',
  timestamp: new Date(),
  userId: '550e8400-e29b-41d4-a716-446655440000',
  type: 'post.created' as const,
  postId: '550e8400-e29b-41d4-a716-446655440001',
  postTitle: 'Hello World'
};

console.log(eventSchema.parse(loginEvent)); // ✅
console.log(eventSchema.parse(logoutEvent)); // ✅
console.log(eventSchema.parse(postEvent)); // ✅

// 13. Record Schema (key-value object)
const configSchema = z.record(z.string(), z.unknown());

const config = {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
  retries: 3,
  features: {
    darkMode: true,
    notifications: false
  }
};

console.log(configSchema.parse(config)); // ✅

// More specific record schema
const themeConfigSchema = z.record(z.enum(['primary', 'secondary', 'success', 'danger', 'warning', 'info']), z.string());

const themeConfig = {
  header: 'primary',
  sidebar: 'secondary',
  buttons: 'success',
  alerts: 'danger',
  notifications: 'warning',
  links: 'info'
};

console.log(themeConfigSchema.parse(themeConfig)); // ✅

// 14. Tuple Schema
const coordinateSchema = z.tuple([z.number(), z.number()]);
const rgbColorSchema = z.tuple([z.number().min(0).max(255), z.number().min(0).max(255), z.number().min(0).max(255)]);

console.log(coordinateSchema.parse([10, 20])); // ✅
console.log(rgbColorSchema.parse([255, 128, 0])); // ✅

// 15. Optional Array Elements
const profileSchema = z.object({
  username: z.string(),
  email: z.string().email(),
  socialLinks: z.array(z.object({
    platform: z.string(),
    url: z.string().url()
  })).optional(),
  skills: z.array(z.string()).optional()
});

const profile = {
  username: 'johndoe',
  email: '[email protected]',
  socialLinks: [
    { platform: 'twitter', url: 'https://twitter.com/johndoe' },
    { platform: 'github', url: 'https://github.com/johndoe' }
  ],
  skills: ['TypeScript', 'React', 'Node.js']
};

console.log(profileSchema.parse(profile)); // ✅

// 16. Recursive Schema (self-referencing)
const categorySchema = z.object({
  id: z.string(),
  name: z.string(),
  description: z.string().optional(),
  parentCategory: z.string().optional()
});

const categoryWithChildren = categorySchema.extend({
  subcategories: z.lazy(() => z.array(categoryWithChildren)).optional()
});

// Valid category with nested children
const categoryTree = {
  id: 'cat1',
  name: 'Technology',
  description: 'All things tech',
  subcategories: [
    {
      id: 'cat2',
      name: 'Programming',
      subcategories: [
        {
          id: 'cat3',
          name: 'JavaScript',
          parentCategory: 'cat2'
        },
        {
          id: 'cat4',
          name: 'Python',
          parentCategory: 'cat2'
        }
      ]
    },
    {
      id: 'cat5',
      name: 'Hardware',
      parentCategory: 'cat1'
    }
  ]
};

console.log(categoryWithChildren.parse(categoryTree)); // ✅

// 17. Complex Validation Examples

// Product schema with inventory management
const productSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(1).max(100),
  description: z.string().max(1000),
  price: z.number().positive(),
  categories: z.array(z.string().uuid()).min(1),
  variants: z.array(z.object({
    id: z.string().uuid(),
    name: z.string(),
    sku: z.string(),
    price: z.number().positive().optional(),
    inventory: z.object({
      quantity: z.number().min(0),
      lowStockThreshold: z.number().min(0),
      trackInventory: z.boolean()
    }),
    attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])),
    images: z.array(z.object({
      url: z.string().url(),
      alt: z.string().optional(),
      isPrimary: z.boolean().default(false)
    }))
  })).min(1),
  tags: z.array(z.string()).max(10).optional(),
  metadata: z.object({
    weight: z.number().positive().optional(),
    dimensions: z.object({
      length: z.number().positive(),
      width: z.number().positive(),
      height: z.number().positive(),
      unit: z.enum(['cm', 'in', 'mm']).default('cm')
    }).optional(),
    seo: z.object({
      title: z.string().max(60).optional(),
      description: z.string().max(160).optional(),
      keywords: z.array(z.string()).max(10).optional()
    }).optional()
  }).optional()
});

// Order schema with line items
const orderItemSchema = z.object({
  productId: z.string().uuid(),
  variantId: z.string().uuid(),
  quantity: z.number().positive().max(100),
  price: z.number().positive(),
  discounts: z.array(z.object({
    type: z.enum(['percentage', 'fixed']),
    value: z.number().positive(),
    reason: z.string().optional()
  })).optional()
});

const orderSchema = z.object({
  id: z.string().uuid(),
  customerId: z.string().uuid(),
  items: z.array(orderItemSchema).min(1),
  status: z.enum(['pending', 'confirmed', 'processing', 'shipped', 'delivered', 'cancelled']),
  shippingAddress: addressSchema,
  billingAddress: addressSchema,
  paymentMethod: z.object({
    type: z.enum(['credit_card', 'debit_card', 'paypal', 'stripe']),
    lastFour: z.string().length(4).regex(/^d+$/),
    brand: z.string().optional()
  }),
  subtotal: z.number().positive(),
  tax: z.number().nonnegative(),
  shipping: z.number().nonnegative(),
  total: z.number().positive(),
  createdAt: z.date(),
  shippedAt: z.date().optional(),
  deliveredAt: z.date().optional()
});

// Validation functions for complex scenarios
function validateProductInventory(product: unknown, requestedQuantity: number) {
  const parsedProduct = productSchema.parse(product);

  for (const variant of parsedProduct.variants) {
    if (variant.inventory.quantity < requestedQuantity) {
      throw new Error(`Insufficient inventory for variant ${variant.name}. Available: ${variant.inventory.quantity}, Requested: ${requestedQuantity}`);
    }

    if (variant.inventory.trackInventory && variant.inventory.quantity <= variant.inventory.lowStockThreshold) {
      console.warn(`Low stock warning for variant ${variant.name}. Current stock: ${variant.inventory.quantity}`);
    }
  }

  return parsedProduct;
}

function validateOrderTotal(order: unknown) {
  const parsedOrder = orderSchema.parse(order);

  const calculatedSubtotal = parsedOrder.items.reduce((sum, item) => {
    const itemTotal = item.price * item.quantity;
    const discountTotal = (item.discounts || []).reduce((discountSum, discount) => {
      if (discount.type === 'percentage') {
        return discountSum + (itemTotal * discount.value / 100);
      } else {
        return discountSum + discount.value;
      }
    }, 0);
    return sum + (itemTotal - discountTotal);
  }, 0);

  if (Math.abs(calculatedSubtotal - parsedOrder.subtotal) > 0.01) {
    throw new Error(`Subtotal mismatch. Calculated: ${calculatedSubtotal}, Provided: ${parsedOrder.subtotal}`);
  }

  const calculatedTotal = calculatedSubtotal + parsedOrder.tax + parsedOrder.shipping;
  if (Math.abs(calculatedTotal - parsedOrder.total) > 0.01) {
    throw new Error(`Total mismatch. Calculated: ${calculatedTotal}, Provided: ${parsedOrder.total}`);
  }

  return parsedOrder;
}

// Test complex validation
try {
  const testProduct = {
    id: '550e8400-e29b-41d4-a716-446655440006',
    name: 'Wireless Headphones',
    description: 'High-quality wireless headphones with noise cancellation',
    price: 99.99,
    categories: ['cat1', 'cat2'],
    variants: [
      {
        id: 'var1',
        name: 'Black',
        sku: 'WH-BLK-001',
        inventory: {
          quantity: 50,
          lowStockThreshold: 10,
          trackInventory: true
        },
        attributes: { color: 'black', wireless: true },
        images: [
          { url: 'https://example.com/headphones-black.jpg', alt: 'Black wireless headphones', isPrimary: true }
        ]
      }
    ]
  };

  validateProductInventory(testProduct, 5); // ✅

  const testOrder = {
    id: 'order1',
    customerId: 'customer1',
    items: [
      {
        productId: 'product1',
        variantId: 'var1',
        quantity: 2,
        price: 99.99
      }
    ],
    status: 'pending' as const,
    shippingAddress: {
      street: '123 Main St',
      city: 'New York',
      state: 'NY',
      zipCode: '10001'
    },
    billingAddress: {
      street: '123 Main St',
      city: 'New York',
      state: 'NY',
      zipCode: '10001'
    },
    paymentMethod: {
      type: 'credit_card' as const,
      lastFour: '1234',
      brand: 'Visa'
    },
    subtotal: 199.98,
    tax: 16.00,
    shipping: 5.00,
    total: 220.98,
    createdAt: new Date()
  };

  validateOrderTotal(testOrder); // ✅
} catch (error) {
  console.error('Complex validation error:', error);
}

export {
  userSchema,
  addressSchema,
  userWithAddressSchema,
  postSchema,
  postsSchema,
  eventSchema,
  productSchema,
  orderItemSchema,
  orderSchema,
  validateProductInventory,
  validateOrderTotal,
  type User,
  type Event
};
QuellcodetypescriptKomplex

Zod Fortgeschrittene Muster

Fortgeschrittene Zod Muster einschließlich benutzerdefinierter Validatoren, Fehlerbehandlung, Schema-Komposition, Middleware und Real-World-Anwendungsfälle

Schwierigkeit

9/10

Geschätzte Zeit

60 min

Schlagwörter

zod, validation, patterns, typescript, advanced

Voraussetzungen

Advanced Zod, TypeScript, Design patterns, Async/await

typescript
// Zod Advanced Patterns and Real-World Examples

import { z, ZodIssue, ZodSchema } from 'zod';

// 1. Custom Validation with Detailed Error Messages

// Enhanced string validation with multiple custom rules
const enhancedStringSchema = z.string()
  .min(3, 'String must be at least 3 characters long')
  .max(100, 'String must be at most 100 characters long')
  .regex(/^[a-zA-Z0-9\s-_]+$/, 'String can only contain letters, numbers, spaces, hyphens, and underscores')
  .refine((val) => val.trim() === val, {
    message: 'String cannot have leading or trailing whitespace'
  })
  .refine((val) => {
    const wordCount = val.trim().split(/\s+/).length;
    return wordCount >= 2;
  }, {
    message: 'String must contain at least 2 words'
  })
  .transform((val) => val.trim());

// Custom ID validator with format checking
const idSchema = z.string()
  .regex(/^[a-zA-Z0-9_-]+$/, 'ID can only contain letters, numbers, hyphens, and underscores')
  .min(3, 'ID must be at least 3 characters long')
  .max(50, 'ID must be at most 50 characters long')
  .refine((val) => /^[a-zA-Z]/.test(val), {
    message: 'ID must start with a letter'
  })
  .refine((val) => !/[-_]{2,}/.test(val), {
    message: 'ID cannot contain consecutive hyphens or underscores'
  });

// 2. Schema Composition and Reuse

// Base field schemas for reuse
const baseFieldSchemas = {
  id: idSchema,
  name: z.string().min(1).max(100),
  description: z.string().max(500).optional(),
  createdAt: z.date(),
  updatedAt: z.date().optional(),
  isActive: z.boolean().default(true)
};

// Timestamp schema with validation
const timestampSchema = z.date()
  .refine((date) => date <= new Date(), {
    message: 'Date cannot be in the future'
  })
  .refine((date) => date >= new Date('2000-01-01'), {
    message: 'Date must be after year 2000'
  });

// 3. Advanced Error Handling

// Custom error formatting
const formatZodError = (error: z.ZodError) => {
  return {
    success: false,
    error: {
      code: error.issues[0]?.code || 'VALIDATION_ERROR',
      message: error.issues[0]?.message || 'Validation failed',
      field: error.issues[0]?.path?.join('.') || 'unknown',
      details: error.issues.map(issue => ({
        field: issue.path?.join('.') || 'unknown',
        code: issue.code,
        message: issue.message,
        received: issue.received,
        expected: issue.expected
      }))
    }
  };
};

// Custom error class for validation
class ValidationError extends Error {
  constructor(
    message: string,
    public readonly code: string,
    public readonly field?: string,
    public readonly details?: ZodIssue[]
  ) {
    super(message);
    this.name = 'ValidationError';
  }
}

// Enhanced safe parse with custom error handling
function safeParseWithCustomError<T>(schema: ZodSchema<T>, data: unknown): T {
  const result = schema.safeParse(data);

  if (!result.success) {
    const firstError = result.error.issues[0];
    throw new ValidationError(
      firstError.message,
      firstError.code,
      firstError.path?.join('.'),
      result.error.issues
    );
  }

  return result.data;
}

// 4. Middleware Pattern for Validation

// Validation middleware type
type ValidationMiddleware<T> = (data: unknown) => T;

// Create validation middleware
function createValidationMiddleware<T>(schema: ZodSchema<T>): ValidationMiddleware<T> {
  return (data: unknown): T => {
    return safeParseWithCustomError(schema, data);
  };
}

// Higher-order function for validation
function withValidation<T>(
  schema: ZodSchema<T>,
  fn: (validatedData: T) => unknown
) {
  const validate = createValidationMiddleware(schema);

  return (data: unknown) => {
    const validatedData = validate(data);
    return fn(validatedData);
  };
}

// 5. Async Validation Patterns

// Async validator for checking uniqueness
async function createUniqueEmailValidator(existingEmails: Set<string>) {
  return async (email: string) => {
    // Simulate database check
    await new Promise(resolve => setTimeout(resolve, 100));

    if (existingEmails.has(email.toLowerCase())) {
      throw new Error('Email already exists');
    }

    return true;
  };
}

// Async schema with custom validation
async function createUserSchema(existingEmails: Set<string> = new Set()) {
  const uniqueEmailValidator = await createUniqueEmailValidator(existingEmails);

  return z.object({
    email: z.string().email().refine(uniqueEmailValidator, {
      message: 'Email must be unique'
    }),
    username: z.string().min(3).max(20).regex(/^[a-zA-Z0-9_]+$/),
    password: z.string()
      .min(8)
      .regex(/[A-Z]/, 'Password must contain uppercase')
      .regex(/[a-z]/, 'Password must contain lowercase')
      .regex(/[0-9]/, 'Password must contain number')
      .regex(/[^A-Za-z0-9]/, 'Password must contain special character')
  });
}

// 6. Conditional Validation

// Conditional object schema based on user type
function createUserProfileSchema(isAdmin: boolean) {
  const baseProfile = z.object({
    firstName: z.string().min(1),
    lastName: z.string().min(1),
    email: z.string().email(),
    bio: z.string().max(500).optional()
  });

  if (isAdmin) {
    return baseProfile.extend({
      adminLevel: z.enum(['junior', 'senior', 'lead']),
      permissions: z.array(z.string()).min(1),
      department: z.string().min(1)
    });
  }

  return baseProfile.extend({
    preferences: z.object({
      theme: z.enum(['light', 'dark']),
      notifications: z.boolean(),
      language: z.string().length(2)
    })
  });
}

// 7. Schema Refactoring with Composition

// Address schema
const addressSchema = z.object({
  street: z.string().min(1),
  city: z.string().min(1),
  state: z.string().length(2),
  zipCode: z.string().regex(/^\d{5}(-\d{4})?$/),
  country: z.string().default('USA'),
  addressType: z.enum(['shipping', 'billing', 'both'])
});

// Contact schema
const contactSchema = z.object({
  phone: z.string().regex(/^\+?[1-9]\d{1,14}$/).optional(),
  email: z.string().email(),
  website: z.string().url().optional(),
  socialMedia: z.record(z.string().url()).optional()
});

// User schema composed from smaller schemas
const createUserSchema = () => z.object({
  ...baseFieldSchemas,
  contact: contactSchema,
  addresses: z.array(addressSchema).min(1),
  role: z.enum(['user', 'admin', 'moderator']).default('user'),
  profile: z.object({
    avatar: z.string().url().optional(),
    timezone: z.string(),
    locale: z.string().default('en-US')
  })
});

// 8. Real-World API Request/Response Validation

// API Request schemas
const PaginationSchema = z.object({
  page: z.coerce.number().positive().default(1),
  limit: z.coerce.number().positive().max(100).default(20),
  sortBy: z.enum(['createdAt', 'updatedAt', 'name']).default('createdAt'),
  sortOrder: z.enum(['asc', 'desc']).default('desc')
});

const FilterSchema = z.object({
  status: z.enum(['active', 'inactive', 'all']).optional(),
  category: z.string().optional(),
  dateFrom: z.string().datetime().optional(),
  dateTo: z.string().datetime().optional(),
  search: z.string().optional()
});

// API Request wrapper
const ApiRequestSchema = z.object({
  pagination: PaginationSchema,
  filters: FilterSchema,
  include: z.array(z.string()).optional()
});

// API Response schemas
const ApiSuccessSchema = <T>(dataSchema: ZodSchema<T>) => z.object({
  success: z.literal(true),
  data: dataSchema,
  pagination: z.object({
    currentPage: z.number(),
    totalPages: z.number(),
    totalItems: z.number(),
    hasNext: z.boolean(),
    hasPrev: z.boolean()
  }).optional(),
  meta: z.record(z.unknown()).optional()
});

const ApiErrorSchema = z.object({
  success: z.literal(false),
  error: z.object({
    code: z.string(),
    message: z.string(),
    details: z.array(z.object({
      field: z.string(),
      code: z.string(),
      message: z.string()
    })).optional()
  }),
  meta: z.record(z.unknown()).optional()
});

// Generic API response schema
const ApiResponseSchema = <T>(dataSchema: ZodSchema<T>) =>
  z.union([ApiSuccessSchema(dataSchema), ApiErrorSchema]);

// 9. Database Model Validation

// UUID validator with fallback
const uuidSchema = z.string().uuid().or(z.string().length(36)).transform((val) => {
  // Handle both UUID and string representation
  return val.length === 36 ? val : val;
});

// Entity status validator
const EntityStatusSchema = z.enum(['active', 'inactive', 'archived', 'pending']).default('active');

// Soft delete mixin
const withSoftDelete = <T extends z.ZodRawShape>(
  schema: T
) => z.object(schema).extend({
  deletedAt: z.date().nullable().default(null),
  deletedBy: uuidSchema.nullable().default(null)
});

// Audit fields mixin
const withAuditFields = <T extends z.ZodRawShape>(
  schema: T
) => z.object(schema).extend({
  createdAt: z.date().default(() => new Date()),
  updatedAt: z.date().default(() => new Date()),
  createdBy: uuidSchema,
  updatedBy: uuidSchema.optional()
});

// 10. Environment Configuration Validation

// Environment type discriminator
const EnvironmentSchema = z.enum(['development', 'staging', 'production', 'test']);

// Database configuration
const DatabaseConfigSchema = z.object({
  url: z.string().url(),
  ssl: z.boolean().default(true),
  maxConnections: z.number().positive().default(10),
  connectionTimeout: z.number().positive().default(30000),
  idleTimeout: z.number().positive().default(300000)
});

// Server configuration
const ServerConfigSchema = z.object({
  port: z.number().positive().default(3000),
  host: z.string().default('localhost'),
  cors: z.object({
    origin: z.union([z.string(), z.array(z.string())]).default('*'),
    credentials: z.boolean().default(false),
    methods: z.array(z.enum(['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'])).default(['GET', 'POST'])
  }).default({}),
  rateLimit: z.object({
    windowMs: z.number().positive().default(900000), // 15 minutes
    maxRequests: z.number().positive().default(100)
  }).optional()
});

// Complete environment configuration
const EnvironmentConfigSchema = z.object({
  nodeEnv: EnvironmentSchema,
  server: ServerConfigSchema,
  database: DatabaseConfigSchema,
  auth: z.object({
    jwtSecret: z.string().min(32),
    jwtExpiresIn: z.string().default('24h'),
    bcryptRounds: z.number().positive().min(10).max(12).default(12)
  }),
  redis: z.object({
    url: z.string().url().optional(),
    host: z.string().default('localhost'),
    port: z.number().positive().default(6379),
    password: z.string().optional(),
    db: z.number().default(0)
  }).optional(),
  features: z.object({
    enableMetrics: z.boolean().default(false),
    enableLogging: z.boolean().default(true),
    enableCache: z.boolean().default(true),
    enableRateLimit: z.boolean().default(true)
  }).default({})
});

// 11. Form Validation Patterns

// Multi-step form schema
const step1Schema = z.object({
  firstName: z.string().min(1),
  lastName: z.string().min(1),
  email: z.string().email(),
  phone: z.string().regex(/^\+?[1-9]\d{1,14}$/)
});

const step2Schema = z.object({
  address: addressSchema,
  preferences: z.object({
    newsletter: z.boolean().default(false),
    marketing: z.boolean().default(false)
  })
});

const step3Schema = z.object({
  paymentMethod: z.enum(['credit_card', 'paypal', 'bank_transfer']),
  terms: z.boolean().refine(val => val === true, {
    message: 'You must accept the terms and conditions'
  })
});

// Multi-step form validator
function validateMultiStepForm(step: number, data: unknown) {
  switch (step) {
    case 1:
      return step1Schema.parse(data);
    case 2:
      return step2Schema.parse(data);
    case 3:
      return step3Schema.parse(data);
    default:
      throw new Error('Invalid step number');
  }
}

// 12. Real-World Usage Examples

// User registration service
class UserService {
  private existingEmails = new Set<string>();
  private existingUsernames = new Set<string>();

  async registerUser(userData: unknown) {
    const userSchema = await this.createUserRegistrationSchema();
    const validatedUser = safeParseWithCustomError(userSchema, userData);

    // Additional business logic
    await this.checkDuplicateEmail(validatedUser.email);
    await this.checkDuplicateUsername(validatedUser.username);

    const user = await this.createUserInDatabase(validatedUser);

    // Update tracking sets
    this.existingEmails.add(user.email.toLowerCase());
    this.existingUsernames.add(user.username.toLowerCase());

    return user;
  }

  private async createUserRegistrationSchema() {
    const uniqueEmailValidator = await this.createUniqueEmailValidator();

    return z.object({
      username: z.string()
        .min(3)
        .max(20)
        .regex(/^[a-zA-Z0-9_]+$/)
        .refine(async (username) => {
          await new Promise(resolve => setTimeout(resolve, 50)); // Simulate async check
          return !this.existingUsernames.has(username.toLowerCase());
        }, {
          message: 'Username already exists'
        }),
      email: z.string().email(),
      password: z.string().min(8),
      confirmPassword: z.string()
    }).refine((data) => data.password === data.confirmPassword, {
      message: 'Passwords do not match',
      path: ['confirmPassword']
    });
  }

  private async createUniqueEmailValidator() {
    return async (email: string) => {
      await new Promise(resolve => setTimeout(resolve, 50));
      return !this.existingEmails.has(email.toLowerCase());
    };
  }

  private async checkDuplicateEmail(email: string) {
    if (this.existingEmails.has(email.toLowerCase())) {
      throw new ValidationError('Email already exists', 'DUPLICATE_EMAIL', 'email');
    }
  }

  private async checkDuplicateUsername(username: string) {
    if (this.existingUsernames.has(username.toLowerCase())) {
      throw new ValidationError('Username already exists', 'DUPLICATE_USERNAME', 'username');
    }
  }

  private async createUserInDatabase(userData: any) {
    // Simulate database insertion
    await new Promise(resolve => setTimeout(resolve, 100));

    return {
      id: Math.random().toString(36).substr(2, 9),
      ...userData,
      createdAt: new Date(),
      updatedAt: new Date()
    };
  }
}

// API request/response handler
class ApiController {
  handleRequest(request: unknown, responseSchema: ZodSchema<any>) {
    try {
      const validatedRequest = safeParseWithCustomError(
        ApiRequestSchema,
        request
      );

      // Process request...
      const data = await this.processRequest(validatedRequest);

      const validatedResponse = ApiSuccessSchema(responseSchema).parse({
        success: true,
        data
      });

      return validatedResponse;

    } catch (error) {
      if (error instanceof ValidationError) {
        return ApiErrorSchema.parse({
          success: false,
          error: {
            code: error.code,
            message: error.message,
            details: error.details?.map(issue => ({
              field: issue.field,
              code: issue.code,
              message: issue.message
            }))
          }
        });
      }

      // Handle other unexpected errors
      return ApiErrorSchema.parse({
        success: false,
        error: {
          code: 'INTERNAL_ERROR',
          message: 'An unexpected error occurred'
        }
      });
    }
  }

  private async processRequest(request: any) {
    // Simulate async processing
    await new Promise(resolve => setTimeout(resolve, 50));
    return { message: 'Request processed successfully' };
  }
}

// 13. Testing with Zod

// Test utilities
function expectValidationSuccess<T>(schema: ZodSchema<T>, data: unknown): T {
  const result = schema.safeParse(data);
  if (!result.success) {
    throw new Error(`Expected validation to succeed, but it failed: ${result.error.message}`);
  }
  return result.data;
}

function expectValidationFailure<T>(schema: ZodSchema<T>, data: unknown, expectedError?: string): void {
  const result = schema.safeParse(data);
  if (result.success) {
    throw new Error('Expected validation to fail, but it succeeded');
  }
  if (expectedError && !result.error.message.includes(expectedError)) {
    throw new Error(`Expected error message to contain "${expectedError}", but got: ${result.error.message}`);
  }
}

// Test examples
function runTests() {
  console.log('Running Zod validation tests...');

  // Test success cases
  const validUser = expectValidationSuccess(userSchema, {
    id: '550e8400-e29b-41d4-a716-446655440000',
    name: 'John Doe',
    email: '[email protected]',
    age: 30
  });
  console.log('✅ Valid user test passed');

  // Test failure cases
  expectValidationFailure(
    userSchema,
    { id: 'invalid-uuid', name: '', email: 'invalid-email', age: -5 },
    'Expected string'
  );
  console.log('✅ Invalid user test passed');

  console.log('All tests completed successfully!');
}

// Execute tests
runTests();

// 14. Schema Documentation Generator

function generateSchemaDocumentation(schema: ZodSchema<any>, name: string): string {
  const description = schema._def.description || name;
  let docs = `# ${name}\n\n${description}\n\n## Schema Definition\n\n`;

  if (schema._def.typeName === 'ZodObject') {
    docs += '| Property | Type | Required | Description |\n';
    docs += '|---------|------|----------|-------------|\n';

    for (const [key, def] of Object.entries(schema._def.shape())) {
      const type = def._def.typeName;
      const required = !def._def.defaultValue;
      const description = def._def.description || '';

      docs += `| ${key} | ${type} | ${required ? 'Yes' : 'No'} | ${description} |\n`;
    }
  }

  return docs;
}

export {
  enhancedStringSchema,
  idSchema,
  formatZodError,
  ValidationError,
  safeParseWithCustomError,
  createValidationMiddleware,
  withValidation,
  ApiRequestSchema,
  ApiResponseSchema,
  EnvironmentConfigSchema,
  validateMultiStepForm,
  UserService,
  ApiController,
  expectValidationSuccess,
  expectValidationFailure,
  generateSchemaDocumentation
};

Werkzeuge

Tools, die oft mit diesem Beispiel genutzt werden

Verwandt

Verwandte Beispielsammlungen

Leitfaden zur Tool-Nutzung

Kontext zum Verständnis dieser Beispielsammlung

Titel

Zod Schema-Validierung

Beschreibung

Zod TypeScript-erste Schema-Validierungs-Beispiele einschließlich Primitiven, Objekten, Arrays, Transformationen, benutzerdefinierten Validatoren und Fehlerbehandlung

Überblick

Zod TypeScript-erste Schema-Validierungs-Beispiele einschließlich Primitiven, Objekten, Arrays, Transformationen, benutzerdefinierten Validatoren und Fehlerbehandlung

Wann verwenden

  • Use this sample set when you want reference inputs for Zod Schema-Validierung.
  • Use it to preview output formats and compare related sample variants.

So funktioniert es

  1. 1Open a sample entry to inspect the prepared example payload or asset.
  2. 2Compare it with related tools to understand how the workflow connects.

Anwendungsfälle

  • Zod Grundlagen und Primitive
  • Zod Objekte und Arrays
  • Zod Fortgeschrittene Muster

FAQ

What is included in Zod Schema-Validierung?

This page includes curated sample entries, related tools, and neighboring sample collections for Zod Schema-Validierung.

Start
Werkzeuge3197
Beispiele593
Visualisierungen461
Dateibetrachter103
Themen229
Schlagwörter333
Bilder, Audio & Video655

Werkzeuge für Bild-, Audio- und Videobearbeitung, Konvertierung und Optimierung

Mathe, Datum & Finanzen644

Rechner, Zahlenwerkzeuge, Datumslogik, Statistik und Finanztools

Design & Farbe296

Werkzeuge für Farben, Layouts, Grafiken, visuelle Gestaltung und Designhilfen

Text & Schreiben209

Werkzeuge für Schreiben, Bereinigung, Formatierung, Extraktion und Textanalyse

Entwicklung & Web193

Entwicklerwerkzeuge, Netzwerk-Utilities, Web-Debugging und Automatisierungshelfer

Konvertierung & Kodierung175

Werkzeuge für Format-, Datei-, Archiv-, Einheiten- und Kodierungskonvertierung

UI-Screenshot strukturieren, prüfen und an die Entwicklung übergeben
Klavierskizze erstellen, MIDI prüfen und Hördemo übergeben
Retro-Spieltexturen prüfen und Ressourcen übergeben
Screenshot-Anleitungen prüfen und Schulungsunterlagen übergeben
Responsive Seitenänderungen prüfen und Bildnachweise übergeben

© 2026 Elysia Tools. Alle Rechte vorbehalten.

DokumentationTarifeÜber unsNutzungsbedingungenDatenschutzerklärungCookiesKontakt

Development

JSON-Schema-zu-Zod-Konverter

Konvertiert JSON/YAML-Definitionen von JSON Schema in direkt nutzbaren Zod-Code fuer TypeScript-Projekte, inklusive verschachtelter Objekte, Arrays, Enums und gaengiger Validierungsregeln

Validation

JSON Schema Validator

Validiert JSON-Daten gegen ein JSON Schema, um Struktur und Datentypen zu überprüfen

AI Tools

MCP-Server-Vertragstester (stdio- + WebSocket-Transport · JSON-Schema-2020-12-Validierung)

Protokollgrundlage (Initialize-Ära, 2024-11-05 … 2025-11-25): Die initialize-Anfrage trägt protocolVersion, Client-Capabilities und clientInfo; der Server antwortet mit serverInfo + capabilities; danach muss der Client die notifications/initialized-Meldung senden. Der offizielle stdio-Transport ist zeilenumbruch-getrenntes JSON-RPC (keine eingebetteten Umbrüche, Logs auf stderr, stdout nur MCP-Nachrichten); WebSocket ist ein Custom-Transport (§ Custom Transports): eine JSON-RPC-Nachricht pro Textframe. Jedes Werkzeug-Schema muss an der Wurzel type:object haben; dieser Tester kompiliert jedes inputSchema mit Ajv 2020-12. sampling ist eine Server→Client-Anfrage: deklariert der Client die Capability, darf der Server sampling/createMessage (messages[] + maxTokens) senden, was der Tester beantwortet und prüft. Die Revision 2026-07-28 definiert einen Stateless-Kern (Server initiieren keine Anfragen mehr); dieser Tester zielt auf die klassische Initialize-Ära und weist dies im Bericht aus. Der Standardmodus verifiziert einen vollständig konformen eingebetteten Referenzserver über zwei Transporte (In-Process-stdio-Strompaar + echtes TCP-WebSocket auf 127.0.0.1) — deterministisch und offline.

Development

JSON-Schema-Generator

Leitet JSON Schema aus Beispiel-JSON ab und unterstuetzt manuelle Anpassung sowie Validierung

Format Conversion

XLSX Sheet zu JSON Schema

Leitet JSON Schema aus Kopfzeilen und Beispielen ab

Development

Datenbank Schema Diff

Vergleicht zwei Datenbankschemas und erstellt einen Migrationsentwurf

Development

Tabellen-Schema-Generator

SQL-Tabellenschema-Definitionen generieren

AI Tools

JSON-Schema-Builder für LLM-Tool-Calling

Definiere ein LLM-Tool einmal und erzeuge validierte Function-Calling-Payloads für OpenAI, Anthropic und Gemini.

Rust

Web Rust Fehlerbehandlungsbeispiele

Web Rust Fehlerbehandlungsbeispiele einschließlich Ausnahmefang, Protokollierung und Parametervalidierung

TypeScript

Web TypeScript Fehlerbehandlungsbeispiele

Web TypeScript Fehlerbehandlungsbeispiele einschließlich Ausnahmenabfang, Protokollierung und Parametervalidierung