К основному содержанию
правило

zod — правило для Cursor: валидация схем в TypeScript

Правило для Cursor задаёт стандарты работы с Zod: строгий режим TypeScript, вывод типов из схем и проверка данных на входе.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/zod.mdc
Открыть на GitHub

Что делает zod

Файл подключается к Cursor как правило и действует на файлы **/*.{ts,tsx}. Внутри — набор требований к схемам Zod: включённый strict: true в tsconfig.json, диапазон зависимости ^3.25.0 || ^4.0.0, вывод типов через z.infer вместо ручных интерфейсов.

Отдельный блок про разбор внешних данных: safeParse для ответов API и форм, parse там, где ошибку нужно бросить сразу. Есть примеры кастомных сообщений об ошибках, трансформаций вроде trim и toLowerCase прямо в схеме, z.coerce для query-параметров и переменных окружения. Разница между optional(), nullable() и default() расписана с примером итогового типа.

Схемы предлагается раскладывать по доменам — schemas/user.schema.ts, schemas/product.schema.ts — вместо одного общего файла. Без strict: true вывод типов в Zod работает иначе, так что в проекте с выключенным строгим режимом правило потянет за собой правку tsconfig.json. Текст обрывается на разделе про юнит-тесты схем, поэтому про остальную часть этого раздела судить не берусь.

Какие задачи решает

  • проверять данные из API до того, как они попадут в код
  • получать типы TypeScript прямо из схемы валидации
  • показывать пользователю понятные сообщения об ошибках формы
  • приводить строки из query-параметров к числам и булевым значениям
  • разложить схемы по доменным файлам вместо одного большого

Примеры запросов агенту

  • добавь схему для ответа API и разбери его через safeParse
  • перепиши этот интерфейс на z.infer от схемы
  • сделай схему для query-параметров с z.coerce

Как установить zod

Вручную: положить файлы

.cursor/rules/zod.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Из того же набора69

vitest Правило задаёт Cursor, как писать юнит- и интеграционные тесты на Vitest: где держать файлы, как изолировать кейсы и мокать модули. ★ 3 579звёзд репо vercel Правило для Cursor с набором рекомендаций по разработке и деплою приложений на Vercel. Пригодится, если агент пишет код для Next.js и вы хотите, чтобы он сразу держал в голове конвенции платформы. ★ 3 579звёзд репо unittest Правило задаёт агенту стандарт оформления тестов на unittest: структура каталогов, имена классов и методов, ассерты, моки. ★ 3 579звёзд репо transformers Правило для Cursor задаёт стиль работы с библиотекой 🤗 Transformers: модульные модели, типизация, Trainer вместо ручных циклов обучения. ★ 3 579звёзд репо tornado Правило для Cursor задаёт стиль кода в Tornado: только async/await для ввода-вывода, полные аннотации типов и один обработчик ошибок на всё приложение. ★ 3 579звёзд репо three-js Правило для Cursor задаёт стандарты разработки на three.js: обработка ошибок WebGL, ленивая загрузка ассетов, оптимизация цикла рендера и освобождение ресурсов. ★ 3 579звёзд репо svelte Правило для Cursor задаёт, как писать компоненты Svelte 5: руны вместо старой реактивности, типизация и ключи в списках. Пригодится, если проект уже на Svelte 5. ★ 3 579звёзд репо streamlit Правило для Cursor задаёт, как писать приложения на Streamlit: кэшировать тяжёлые операции, держать UI отдельно от логики и разбивать проект на модули. ★ 3 579звёзд репо

Похожие

zod-validation-utilities giuseppe-trisciuoglio Помогает писать схемы Zod v4 для проверки API, форм и конфигурации в TypeScript. Пригодится для разбора внешних данных и понятной обработки ошибок. CX Codex +1 3 800установок zod-schema-validation Mindrally Скилл задаёт правила валидации данных через Zod и вывода типов TypeScript на границах системы: в API, формах и внешних ответах. Помогает писать схемы без лишнего дублирования. CX Codex +1 1 200установок react-hook-form-zod ovachiever Скилл учит агента собирать формы на React Hook Form с валидацией через Zod. Одна схема работает и на клиенте, и на сервере. CX Codex +1 722установок zod-4 prowler-cloud Скилл обучает ассистента правилам валидации Zod 4 и миграции со старых версий. Он нужен при создании схем для форм, парсинга запросов и адаптеров. CX Codex +1 1 200установок valibot open-circle Скилл учит агента работать с Valibot: создавать схемы, парсить ввод и не путать синтаксис с Zod. Пригодится, когда в проекте уже стоит эта библиотека. CX Codex +1 2 100установок typescript-core bobmatnyc Скилл с современными паттернами TypeScript: строгий tsconfig, валидация данных во время выполнения, продвинутые типы. Пригодится, когда проект на TS растёт и типы перестают спасать. CX Codex +1 475установок

Рядом в теме «Языки программирования»

Все правила IDE по теме «Языки программирования» →

Вопросы о zod

Как установить правило zod в Cursor?

Создайте файл .cursor/rules/zod.mdc в проекте и вставьте в него содержимое правила.

Что делает правило zod?

Задаёт набор практик для схем Zod в TypeScript: строгий режим, вывод типов, разбор недоверенных данных, модульная организация схем.

Нужен ли строгий режим TypeScript для этого правила?

Да, вывод типов в Zod опирается на strict: true в tsconfig.json, и правило требует его включить.

Исходный текст

zod.mdc · CC0-1.0
---
description: This guide outlines definitive best practices for using Zod in TypeScript projects, ensuring robust runtime validation, superior type safety, and maintainable schemas.
globs: **/*.{ts,tsx}
---
# Zod Best Practices

Zod is the definitive TypeScript-first schema validation library. It provides static type inference directly from runtime schemas, catching data-shape errors at both compile time and runtime. Adhere to these guidelines to build resilient, type-safe applications with Zod 4.

## Core Setup & Principles

### 1. Enable Strict TypeScript

Zod's type inference relies on `strict: true` in your `tsconfig.json`. This is non-negotiable for reliable type safety.

```json
// tsconfig.json
{
  "compilerOptions": {
    "strict": true, // ✅ ALWAYS enable strict mode
    // ...
  }
}
```

### 2. Standardize Zod 4 Adoption

Ensure your project and any Zod-dependent libraries use the modern Zod 4 core.

```json
// package.json
{
  "dependencies": {
    "zod": "^3.25.0 || ^4.0.0" // ✅ Use this peer dependency range
  }
}
```

### 3. Leverage Type Inference (`z.infer`)

Always infer types from your schemas. This eliminates duplication and keeps types synchronized with validation logic.

```typescript
import { z } from 'zod';

const userSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(1),
  email: z.string().email(),
});

// ❌ BAD: Manually defining types
interface User {
  id: string;
  name: string;
  email: string;
}

// ✅ GOOD: Infer types directly from the schema
type User = z.infer<typeof userSchema>;

function processUser(user: User) {
  console.log(user.email);
}
```

## Data Validation & Error Handling

### 4. Always Parse Untrusted Data

Never trust external data. Use `schema.parse()` or `schema.safeParse()` immediately upon receiving data from APIs, forms, or environment variables.

```typescript
import { z } from 'zod';

const idSchema = z.string().uuid();

// ❌ BAD: Assuming data is valid
function processId(id: string) {
  // This 'id' could be anything if not validated
  console.log(id.toUpperCase());
}

// ✅ GOOD: Use safeParse for external/untrusted data
function handleRequest(rawId: unknown) {
  const result = idSchema.safeParse(rawId);
  if (!result.success) {
    console.error('Invalid ID received:', result.error.issues);
    return { status: 400, message: 'Invalid ID' };
  }
  // Data is now type-safe and validated
  processId(result.data);
  return { status: 200, message: 'ID processed' };
}

// ✅ GOOD: Use parse for trusted data or when immediate error throwing is desired
function loadConfig(envVar: unknown) {
  try {
    const config = z.object({ API_KEY: z.string().min(1) }).parse(envVar);
    console.log('Config loaded:', config.API_KEY);
  } catch (error) {
    if (error instanceof z.ZodError) {
      console.error('Invalid environment config:', error.issues);
      process.exit(1); // Critical error, exit application
    }
    throw error;
  }
}
```

### 5. Customize Error Messages for UX

Provide clear, user-friendly error messages directly within your schemas.

```typescript
import { z } from 'zod';

const loginSchema = z.object({
  email: z.string().email({ message: 'Invalid email address.' }), // ✅ Custom message
  password: z.string().min(8, { message: 'Password must be at least 8 characters.' }), // ✅ Custom message
});

// Integrate with form libraries (e.g., React Hook Form)
// const { register, handleSubmit, formState: { errors } } = useForm({
//   resolver: zodResolver(loginSchema),
// });
```

## Schema Design & Organization

### 6. Keep Schemas Modular & Domain-Specific

Organize schemas into small, focused files based on their domain. Avoid monolithic schema files.

```
// ❌ BAD: monolithic schemas.ts
// schemas.ts
export const userSchema = z.object({ /* ... */ });
export const productSchema = z.object({ /* ... */ });
export const orderSchema = z.object({ /* ... */ });

// ✅ GOOD: modular, domain-specific files
// schemas/user.schema.ts
export const userSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(1),
  email: z.string().email(),
});

// schemas/product.schema.ts
export const productSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(3),
  price: z.number().positive(),
});

// schemas/index.ts (optional re-export)
export * from './user.schema';
export * from './product.schema';
```

### 7. Use Transforms and Refinements for Data Normalization

Normalize and sanitize data as part of validation.

```typescript
import { z } from 'zod';

// ❌ BAD: Manual post-validation processing
const emailInputSchemaBad = z.string().email();
const processEmailBad = (email: string) => email.toLowerCase().trim();

// ✅ GOOD: Integrate transforms directly into the schema
const emailInputSchema = z
  .string()
  .trim() // ✅ Trim whitespace
  .toLowerCase() // ✅ Convert to lowercase
  .email({ message: 'Invalid email address' });

const postIdSchema = z.string().uuid().transform((val) => `post-${val}`); // ✅ Transform data type or format

const passwordSchema = z.string()
  .min(8)
  .refine(val => /[A-Z]/.test(val), { message: 'Password must contain an uppercase letter' }); // ✅ Refine with custom logic
```

### 8. Prefer `z.coerce` for Type Coercion

Use `z.coerce` for explicit type conversion of known string inputs (e.g., from query parameters, environment variables).

```typescript
import { z } from 'zod';

// ❌ BAD: Manual parsing or loose validation
const pageParamBad = z.string(); // Will be '1' not 1
const pageNumberBad = parseInt(pageParamBad.parse('10'));

// ✅ GOOD: Coerce directly in the schema
const querySchema = z.object({
  page: z.coerce.number().int().positive().default(1), // ✅ Coerces '10' to 10
  isActive: z.coerce.boolean().default(false), // ✅ Coerces 'true'/'false' to boolean
});

const { page, isActive } = querySchema.parse({ page: '5', isActive: 'true' });
console.log(page, typeof page); // 5, 'number'
console.log(isActive, typeof isActive); // true, 'boolean'
```

### 9. Differentiate `optional()`, `nullable()`, and `default()`

Understand the nuances for robust schema design.

```typescript
import { z } from 'zod';

const userProfileSchema = z.object({
  username: z.string(),
  // ✅ optional(): field can be present or absent (undefined)
  bio: z.string().optional(),
  // ✅ nullable(): field can be present with a value or null
  website: z.string().url().nullable(),
  // ✅ default(): provides a fallback value if field is undefined
  status: z.enum(['active', 'inactive']).default('active'),
});

type UserProfile = z.infer<typeof userProfileSchema>;
/*
{
  username: string;
  bio?: string | undefined;
  website: string | null;
  status: "active" | "inactive";
}
*/
```

## Testing & Maintenance

### 10. Write Schema-Focused Unit Tests

Thoroughly test your Zod schemas with both valid and invalid data to prevent regressions.

```typescript
// tests/schemas/user.schema.test.ts
import { userSchema } from '../../schemas/user.schema';

describe('userSchema', () => {
  it('should validate a valid user object', () => {
    const validUser = {
      id: 'a1b2c3d4-e5f6-7890-1234-567890abcdef',
      name: 'John Doe',
      email: '[email protected]',
    };
    expect(() => userSchema.parse(validUser)).not.toThrow(); // ✅ Validates successfully
  });

  it('should invalidate an invalid email', () => {
    const invalidUser = {
      id: 'a1b2c3d4-e5f6-7890-1234-567890abcdef',
      name: 'John Doe',
      email: 'invalid-email',
    };
    const result = userSchema.safeParse(invalidUser);
    expect(result.success).toBe(false); // ✅ Fails validation
    if (!result.success) {
      expect(result.error.issues[0].message).toBe('Invalid email'); // ✅ Specific error message
    }
  });
});
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой