スキル一覧に戻る
mgd34msu

yup

by mgd34msu

Plug in, Receive good vibes.

2🍴 0📅 2026年1月25日
GitHubで見るManusで実行

SKILL.md


name: yup description: 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.

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.

スコア

総合スコア

60/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です