搜索

PythonReactSEOPDF
GitHub Skill

yup

Validates data with Yup schema builder using chainable methods, custom rules, and TypeScript inference. Use when validating forms with React Hook Form or Formik, or when needing flexible schema validation.

mgd34msu☆ 3 仓库 Stars0 仓库 Forks

安装与使用

请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。

查看来源 ↗使用指南

技能说明

Yup

Schema validation library with a fluent, chainable API for JavaScript and TypeScript.

Quick Start

npm install yup
import * as yup from 'yup';

const schema = yup.object({
  name: yup.string().required(),
  email: yup.string().email().required(),
  age: yup.number().positive().integer(),
});

// Validate
const data = await schema.validate({ name: 'John', email: 'john@example.com' });

// Check validity
const isValid = await schema.isValid(data);

Schema Types

String
yup.string()
  .required('Name is required')
  .min(2, 'At least 2 characters')
  .max(50, 'At most 50 characters')
  .matches(/^[a-zA-Z]+$/, 'Only letters')
  .email('Invalid email')
  .url('Invalid URL')
  .uuid('Invalid UUID')
  .lowercase()
  .uppercase()
  .trim()
  .default('Anonymous')
Number
yup.number()
  .required('Required')
  .min(0, 'Must be positive')
  .max(100, 'Max 100')
  .positive('Must be positive')
  .negative('Must be negative')
  .integer('Must be integer')
  .moreThan(0, 'Greater than 0')
  .lessThan(100, 'Less than 100')
  .truncate()
  .round()
  .default(0)
Boolean
yup.boolean()
  .required()
  .isTrue('Must accept terms')
  .isFalse()
  .default(false)
Date
yup.date()
  .required()
  .min(new Date(), 'Must be in the future')
  .max(new Date('2030-12-31'), 'Too far ahead')
  .default(() => new Date())
Array
yup.array()
  .of(yup.string().required())
  .min(1, 'At least one item')
  .max(5, 'At most 5 items')
  .required()
  .default([])

// Tuple-like array
yup.tuple([
  yup.string().required(),
  yup.number().required(),
])
Object
yup.object({
  name: yup.string().required(),
  age: yup.number().positive(),
})
  .noUnknown() // Reject unknown keys
  .strict()    // Don't coerce types
Mixed (Any Type)
yup.mixed()
  .oneOf(['option1', 'option2'], 'Must be option1 or option2')
  .notOneOf(['forbidden'])
  .required()

Common Patterns

User Registration
const registrationSchema = yup.object({
  email: yup.string()
    .email('Invalid email')
    .required('Email is required'),

  password: yup.string()
    .min(8, 'At least 8 characters')
    .matches(/[a-z]/, 'Need lowercase letter')
    .matches(/[A-Z]/, 'Need uppercase letter')
    .matches(/[0-9]/, 'Need number')
    .required('Password is required'),

  confirmPassword: yup.string()
    .oneOf([yup.ref('password')], 'Passwords must match')
    .required('Confirm password'),

  age: yup.number()
    .positive()
    .integer()
    .min(18, 'Must be 18+')
    .required('Age is required'),

  terms: yup.boolean()
    .isTrue('Must accept terms'),
});
Address
const addressSchema = yup.object({
  street: yup.string().required(),
  city: yup.string().required(),
  state: yup.string().length(2).required(),
  zip: yup.string()
    .matches(/^\d{5}(-\d{4})?$/, 'Invalid ZIP')
    .required(),
  country: yup.string().default('US'),
});
Payment
const paymentSchema = yup.object({
  cardNumber: yup.string()
    .matches(/^\d{16}$/, 'Invalid card number')
    .required(),

  expiry: yup.string()
    .matches(/^(0[1-9]|1[0-2])\/\d{2}$/, 'MM/YY format')
    .required(),

  cvv: yup.string()
    .matches(/^\d{3,4}$/, 'Invalid CVV')
    .required(),

  amount: yup.number()
    .positive()
    .required(),
});

Conditional Validation

when() - Field Dependencies
const schema = yup.object({
  hasCompany: yup.boolean(),

  companyName: yup.string().when('hasCompany', {
    is: true,
    then: (schema) => schema.required('Company name required'),
    otherwise: (schema) => schema.notRequired(),
  }),
});
Multiple Conditions
const schema = yup.object({
  type: yup.string().oneOf(['personal', 'business']),
  taxId: yup.string(),
  ssn: yup.string(),
}).test('tax-info', 'Tax info required', function(value) {
  if (value.type === 'business') {
    return !!value.taxId;
  }
  return !!value.ssn;
});

Custom Validation

test() Method
const schema = yup.string().test(
  'is-valid-username',
  'Username already taken',
  async (value) => {
    if (!value) return true;
    const available = await checkUsername(value);
    return available;
  }
);
With Context
const schema = yup.object({
  password: yup.string().required(),
  confirmPassword: yup.string()
    .test('passwords-match', 'Passwords must match', function(value) {
      return value === this.parent.password;
    }),
});
addMethod() - Reusable Validators
yup.addMethod(yup.string, 'phone', function(message) {
  return this.test('phone', message || 'Invalid phone', (value) => {
    if (!value) return true;
    return /^\+?[\d\s-()]+$/.test(value);
  });
});

// Usage
const schema = yup.object({
  phone: yup.string().phone('Invalid phone number'),
});

Type Inference

InferType
const userSchema = yup.object({
  name: yup.string().required(),
  email: yup.string().email().required(),
  age: yup.number().positive(),
});

type User = yup.InferType<typeof userSchema>;
// { name: string; email: string; age: number | undefined }
With Defaults
const schema = yup.object({
  role: yup.string().default('user'),
  active: yup.boolean().default(true),
});

type Config = yup.InferType<typeof schema>;
// { role: string; active: boolean }

Transformation

cast() - Transform Values
const schema = yup.string().trim().lowercase();
const result = schema.cast('  HELLO  '); // 'hello'
transform() - Custom Transforms
const schema = yup.string().transform((value) => {
  return value?.replace(/\s+/g, ' ').trim();
});
Object Transform
const schema = yup.object({
  firstName: yup.string(),
  lastName: yup.string(),
}).transform((value) => ({
  ...value,
  fullName: `${value.firstName} ${value.lastName}`,
}));

Validation Options

validate()
try {
  const result = await schema.validate(data, {
    abortEarly: false,      // Collect all errors
    stripUnknown: true,     // Remove unknown keys
    strict: false,          // Allow coercion
    context: { user: currentUser },
  });
} catch (err) {
  if (err instanceof yup.ValidationError) {
    console.log(err.errors);  // All error messages
    console.log(err.inner);   // Detailed errors
  }
}
validateSync()
try {
  const result = schema.validateSync(data);
} catch (err) {
  // Handle error
}
isValid()
const valid = await schema.isValid(data);

React Hook Form Integration

import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';

const schema = yup.object({
  email: yup.string().email().required(),
  password: yup.string().min(8).required(),
});

type FormData = yup.InferType<typeof schema>;

function Form() {
  const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
    resolver: yupResolver(schema),
  });

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('email')} />
      {errors.email && <span>{errors.email.message}</span>}

      <input {...register('password')} type="password" />
      {errors.password && <span>{errors.password.message}</span>}

      <button type="submit">Submit</button>
    </form>
  );
}

Formik Integration

import { Formik, Form, Field, ErrorMessage } from 'formik';

const schema = yup.object({
  email: yup.string().email().required(),
});

function MyForm() {
  return (
    <Formik
      initialValues={{ email: '' }}
      validationSchema={schema}
      onSubmit={handleSubmit}
    >
      <Form>
        <Field name="email" type="email" />
        <ErrorMessage name="email" />
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  );
}

See references/methods.md for complete method reference.

使用示例

查看来源仓库中的使用示例与配置说明。

查看来源 ↗

来源历史

收录时间
2026-01-20
索引更新时间
2026-01-28
Branch
main

收录与同步日期属于本站记录。源码修改历史请查看来源仓库。

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!