Да, это построитель схем для анализа и проверки значений во время выполнения. Определите схему, преобразуйте значение для соответствия, утвердите форму существующего значения или и то, и другое. Да, схемы чрезвычайно выразительны и позволяют моделировать сложные, взаимозависимые проверки или преобразования значений.
Вы просматриваете документацию для версии 1.0.0, да, документы до версии 1 доступны: здесь
Особенности убийцы :
Схема состоит из действий синтаксического анализа (преобразований), а также утверждений (тестов) относительно входного значения. Проверьте входное значение, чтобы проанализировать его и выполнить настроенный набор утверждений. Объедините методы для построения схемы.
import { object , string , number , date , InferType } from 'yup' ;
let userSchema = object ( {
name : string ( ) . required ( ) ,
age : number ( ) . required ( ) . positive ( ) . integer ( ) ,
email : string ( ) . email ( ) ,
website : string ( ) . url ( ) . nullable ( ) ,
createdOn : date ( ) . default ( ( ) => new Date ( ) ) ,
} ) ;
// parse and assert validity
let user = await userSchema . validate ( await fetchUser ( ) ) ;
type User = InferType < typeof userSchema > ;
/* {
name: string;
age: number;
email?: string | undefined
website?: string | null | undefined
createdOn: Date
}*/
Используйте схему, чтобы привести или «привести» входное значение к правильному типу и, при необходимости, преобразовать это значение в более конкретные и конкретные значения, не делая дальнейших утверждений.
// Attempts to coerce values to the correct type
let parsedUser = userSchema . cast ( {
name : 'jimmy' ,
age : '24' ,
createdOn : '2014-09-23T19:25:25Z' ,
} ) ;
// ✅ { name: 'jimmy', age: 24, createdOn: Date }
Знаете ли вы, что ваше входное значение уже проанализировано? Вы можете «строго» проверить входные данные и избежать накладных расходов на выполнение логики синтаксического анализа.
// ValidationError "age is not a number"
let parsedUser = await userSchema . validate (
{
name : 'jimmy' ,
age : '24' ,
} ,
{ strict : true } ,
) ;
yup
reach(schema: Schema, path: string, value?: object, context?: object): Schema
addMethod(schemaType: Schema, name: string, method: ()=> Schema): void
ref(path: string, options: { contextPrefix: string }): Ref
lazy((value: any) => Schema): Lazy
ValidationError(errors: string | Array<string>, value: any, path: string)
Schema
Schema.clone(): Schema
Schema.label(label: string): Schema
Schema.meta(metadata: SchemaMetadata): Schema
Schema.describe(options?: ResolveOptions): SchemaDescription
Schema.concat(schema: Schema): Schema
Schema.validate(value: any, options?: object): Promise<InferType<Schema>, ValidationError>
Schema.validateSync(value: any, options?: object): InferType<Schema>
Schema.validateAt(path: string, value: any, options?: object): Promise<InferType<Schema>, ValidationError>
Schema.validateSyncAt(path: string, value: any, options?: object): InferType<Schema>
Schema.isValid(value: any, options?: object): Promise<boolean>
Schema.isValidSync(value: any, options?: object): boolean
Schema.cast(value: any, options = {}): InferType<Schema>
Schema.isType(value: any): value is InferType<Schema>
Schema.strict(enabled: boolean = false): Schema
Schema.strip(enabled: boolean = true): Schema
Schema.withMutation(builder: (current: Schema) => void): void
Schema.default(value: any): Schema
Schema.getDefault(options?: object): Any
Schema.nullable(message?: string | function): Schema
Schema.nonNullable(message?: string | function): Schema
Schema.defined(): Schema
Schema.optional(): Schema
Schema.required(message?: string | function): Schema
Schema.notRequired(): Schema
Schema.typeError(message: string): Schema
Schema.oneOf(arrayOfValues: Array<any>, message?: string | function): Schema
: equals
Schema.notOneOf(arrayOfValues: Array<any>, message?: string | function)
Schema.when(keys: string | string[], builder: object | (values: any[], schema) => Schema): Schema
Schema.test(name: string, message: string | function | any, test: function): Schema
Schema.test(options: object): Schema
Schema.transform((currentValue: any, originalValue: any) => any): Schema
string.required(message?: string | function): Schema
string.length(limit: number | Ref, message?: string | function): Schema
string.min(limit: number | Ref, message?: string | function): Schema
string.max(limit: number | Ref, message?: string | function): Schema
string.matches(regex: Regex, message?: string | function): Schema
string.matches(regex: Regex, options: { message: string, excludeEmptyString: bool }): Schema
string.email(message?: string | function): Schema
string.url(message?: string | function): Schema
string.uuid(message?: string | function): Schema
string.datetime(options?: {message?: string | function, allowOffset?: boolean, precision?: number})
string.datetime(message?: string | function)
string.ensure(): Schema
string.trim(message?: string | function): Schema
string.lowercase(message?: string | function): Schema
string.uppercase(message?: string | function): Schema
number.min(limit: number | Ref, message?: string | function): Schema
number.max(limit: number | Ref, message?: string | function): Schema
number.lessThan(max: number | Ref, message?: string | function): Schema
number.moreThan(min: number | Ref, message?: string | function): Schema
number.positive(message?: string | function): Schema
number.negative(message?: string | function): Schema
number.integer(message?: string | function): Schema
number.truncate(): Schema
number.round(type: 'floor' | 'ceil' | 'trunc' | 'round' = 'round'): Schema
date.min(limit: Date | string | Ref, message?: string | function): Schema
date.max(limit: Date | string | Ref, message?: string | function): Schema
array.of(type: Schema): this
array.json(): this
array.length(length: number | Ref, message?: string | function): this
array.min(limit: number | Ref, message?: string | function): this
array.max(limit: number | Ref, message?: string | function): this
array.ensure(): this
array.compact(rejector: (value) => boolean): Schema
object.shape(fields: object, noSortEdges?: Array<[string, string]>): Schema
object.json(): this
object.concat(schemaB: ObjectSchema): ObjectSchema
object.pick(keys: string[]): Schema
object.omit(keys: string[]): Schema
object.from(fromKey: string, toKey: string, alias: boolean = false): this
object.noUnknown(onlyKnownKeys: boolean = true, message?: string | function): Schema
object.camelCase(): Schema
object.constantCase(): Schema
Определения схемы состоят из «преобразований» синтаксического анализа, которые преобразуют входные данные в желаемую форму и тип, «тестов», которые делают утверждения по анализируемым данным. Схема также хранит множество «метаданных», подробностей о самой схеме, которые можно использовать для улучшения сообщений об ошибках, создания инструментов, динамически использующих схему, или сериализации схемы в другой формат.
Чтобы быть максимально гибким, да, можно запускать как синтаксический анализ, так и утверждения отдельно для удовлетворения конкретных потребностей.
Каждый встроенный тип реализует базовый анализ типов, который полезен при анализе сериализованных данных, таких как JSON. Кроме того, типы реализуют преобразования, специфичные для типа, которые можно включить.
let num = number ( ) . cast ( '1' ) ; // 1
let obj = object ( {
firstName : string ( ) . lowercase ( ) . trim ( ) ,
} )
. json ( )
. camelCase ( )
. cast ( '{"first_name": "jAnE "}' ) ; // { firstName: 'jane' }
Могут быть добавлены пользовательские преобразования
let reversedString = string ( )
. transform ( ( currentValue ) => currentValue . split ( '' ) . reverse ( ) . join ( '' ) )
. cast ( 'dlrow olleh' ) ; // "hello world"
Преобразования образуют «конвейер», в котором значение предыдущего преобразования передается по конвейеру в следующее. Если входное значение undefined
, да, будет применена схема по умолчанию, если она настроена.
Осторожно! значения не обязательно являются допустимыми типами в функциях преобразования. Предыдущие преобразования могли завершиться неудачно. Например, числовое преобразование может принимать входное значение
NaN
или число.
Да, схема запускает «тесты» над входными значениями. Тесты утверждают, что входные данные соответствуют некоторым критериям. Тесты отличаются от преобразований тем, что они не изменяют и не изменяют входные данные (или их тип) и обычно предназначены для проверок, которые сложно, если не невозможно, представить в статических типах.
string ( )
. min ( 3 , 'must be at least 3 characters long' )
. email ( 'must be a valid email' )
. validate ( 'no' ) ; // ValidationError
Как и в случае с преобразованиями, тесты можно настраивать «на лету».
let jamesSchema = string ( ) . test (
'is-james' ,
( d ) => ` ${ d . path } is not James` ,
( value ) => value == null || value === 'James' ,
) ;
jamesSchema . validateSync ( 'James' ) ; // "James"
jamesSchema . validateSync ( 'Jane' ) ; // ValidationError "this is not James"
Внимание: в отличие от преобразований,
value
в пользовательском тесте гарантированно имеет правильный тип (в данном случае необязательная строка). Оно по-прежнему может бытьundefined
илиnull
в зависимости от вашей схемы. В этих случаях вы можете захотеть вернутьtrue
для отсутствующих значений, если только ваше преобразование не делает утверждения, связанные с присутствием. Опция тестированияskipAbsent
сделает это за вас, если она установлена.
В простейшем случае тестовая функция возвращает true
или false
в зависимости от того, прошла ли проверка. В случае неудачного теста да, выдаст ValidationError
с вашим сообщением (или сообщением по умолчанию) для этого теста. ValidationErrors также содержит множество других метаданных о тесте, включая его имя, аргументы (если таковые имеются), с которыми он был вызван, и путь к полю с ошибкой в случае вложенной проверки.
Сообщения об ошибках также можно создавать «на лету», чтобы настроить способ сбоя схемы.
let order = object ( {
no : number ( ) . required ( ) ,
sku : string ( ) . test ( {
name : 'is-sku' ,
skipAbsent : true ,
test ( value , ctx ) {
if ( ! value . startsWith ( 's-' ) ) {
return ctx . createError ( { message : 'SKU missing correct prefix' } )
}
if ( ! value . endsWith ( '-42a' ) ) {
return ctx . createError ( { message : 'SKU missing correct suffix' } )
}
if ( value . length < 10 ) {
return ctx . createError ( { message : 'SKU is not the right length' } )
}
return true
}
} )
} )
order . validate ( { no : 1234 , sku : 's-1a45-14a' } )
Схема неизменяема, каждый вызов метода возвращает новый объект схемы. Используйте повторно и передавайте их, не опасаясь мутации другого экземпляра.
let optionalString = string ( ) . optional ( ) ;
let definedString = optionalString . defined ( ) ;
let value = undefined ;
optionalString . isValid ( value ) ; // true
definedString . isValid ( value ) ; // false
Да, схема создает статические интерфейсы TypeScript. Используйте InferType
для извлечения этого интерфейса:
import * as yup from 'yup' ;
let personSchema = yup . object ( {
firstName : yup . string ( ) . defined ( ) ,
nickName : yup . string ( ) . default ( '' ) . nullable ( ) ,
sex : yup
. mixed ( )
. oneOf ( [ 'male' , 'female' , 'other' ] as const )
. defined ( ) ,
email : yup . string ( ) . nullable ( ) . email ( ) ,
birthDate : yup . date ( ) . nullable ( ) . min ( new Date ( 1900 , 0 , 1 ) ) ,
} ) ;
interface Person extends yup . InferType < typeof personSchema > {
// using interface instead of type generally gives nicer editor feedback
}
Значение схемы по умолчанию используется, когда приведение приводит к undefined
выходному значению. По этой причине установка значения по умолчанию влияет на тип вывода схемы, по сути отмечая его как «определенный()».
import { string } from 'yup' ;
let value : string = string ( ) . default ( 'hi' ) . validate ( undefined ) ;
// vs
let value : string | undefined = string ( ) . validate ( undefined ) ;
В некоторых случаях тип TypeScript уже существует, и вы хотите убедиться, что ваша схема создает совместимый тип:
import { object , number , string , ObjectSchema } from 'yup' ;
interface Person {
name : string ;
age ?: number ;
sex : 'male' | 'female' | 'other' | null ;
}
// will raise a compile-time type error if the schema does not produce a valid Person
let schema : ObjectSchema < Person > = object ( {
name : string ( ) . defined ( ) ,
age : number ( ) . optional ( ) ,
sex : string < 'male' | 'female' | 'other' > ( ) . nullable ( ) . defined ( ) ,
} ) ;
// errors:
// "Type 'number | undefined' is not assignable to type 'string'."
let badSchema : ObjectSchema < Person > = object ( {
name : number ( ) ,
} ) ;
При необходимости вы можете использовать поведение слияния интерфейса TypeScript, чтобы расширить типы схем. Расширения типов должны находиться в «окружающем» файле определения типа, таком как globals.d.ts
. Не забудьте расширить тип yup в коде вашего приложения!
Осторожно! слияние работает только в том случае, если определение типа точно такое же, включая дженерики. Обратитесь к исходному коду каждого типа, чтобы убедиться, что вы его правильно определяете.
// globals.d.ts
declare module 'yup' {
interface StringSchema < TType , TContext , TDefault , TFlags > {
append ( appendStr : string ) : this ;
}
}
// app.ts
import { addMethod , string } from 'yup' ;
addMethod ( string , 'append' , function append ( appendStr : string ) {
return this . transform ( ( value ) => ` ${ value } ${ appendStr } ` ) ;
} ) ;
string ( ) . append ( '~~~~' ) . cast ( 'hi' ) ; // 'hi~~~~'
Чтобы вывод типа работал, у вас должна быть включена опция компилятора strictNullChecks
.
Мы также рекомендуем установить для strictFunctionTypes
значение false
для функционально лучших типов. Да, это снижает общую надежность, однако TypeScript уже отключает эту проверку для методов и конструкторов (примечание из документации TS):
Во время разработки этой функции мы обнаружили большое количество небезопасных по своей сути иерархий классов, в том числе в DOM. По этой причине этот параметр применяется только к функциям, написанным с синтаксисом функции, а не с синтаксисом метода:
Ваш опыт будет разным, но мы обнаружили, что эта проверка не предотвращает многих реальных ошибок, но увеличивает количество обременительного явного приведения типов в приложениях.
Сообщения об ошибках по умолчанию можно настроить на случай, если в ходе проверочного теста не будет получено ни одного сообщения. Если какое-либо сообщение отсутствует в пользовательском словаре, сообщение об ошибке по умолчанию будет сообщением Да.
import { setLocale } from 'yup' ;
setLocale ( {
mixed : {
default : 'Não é válido' ,
} ,
number : {
min : 'Deve ser maior que ${min}' ,
} ,
} ) ;
// now use Yup schemas AFTER you defined your custom dictionary
let schema = yup . object ( ) . shape ( {
name : yup . string ( ) ,
age : yup . number ( ) . min ( 18 ) ,
} ) ;
try {
await schema . validate ( { name : 'jimmy' , age : 11 } ) ;
} catch ( err ) {
err . name ; // => 'ValidationError'
err . errors ; // => ['Deve ser maior que 18']
}
Если вам нужна многоязычная поддержка, да, она вам поможет. Функция setLocale
принимает функции, которые можно использовать для создания объектов ошибок с ключами и значениями перевода. Их можно загрузить в вашу любимую библиотеку i18n.
import { setLocale } from 'yup' ;
setLocale ( {
// use constant translation keys for messages without values
mixed : {
default : 'field_invalid' ,
} ,
// use functions to generate an error object that includes the value from the schema
number : {
min : ( { min } ) => ( { key : 'field_too_short' , values : { min } } ) ,
max : ( { max } ) => ( { key : 'field_too_big' , values : { max } } ) ,
} ,
} ) ;
// ...
let schema = yup . object ( ) . shape ( {
name : yup . string ( ) ,
age : yup . number ( ) . min ( 18 ) ,
} ) ;
try {
await schema . validate ( { name : 'jimmy' , age : 11 } ) ;
} catch ( err ) {
messages = err . errors . map ( ( err ) => i18next . t ( err . key ) ) ;
}
yup
Модуль экспорта.
// core schema
import {
mixed ,
string ,
number ,
boolean ,
bool ,
date ,
object ,
array ,
ref ,
lazy ,
} from 'yup' ;
// Classes
import {
Schema ,
MixedSchema ,
StringSchema ,
NumberSchema ,
BooleanSchema ,
DateSchema ,
ArraySchema ,
ObjectSchema ,
} from 'yup' ;
// Types
import type { InferType , ISchema , AnySchema , AnyObjectSchema } from 'yup' ;
reach(schema: Schema, path: string, value?: object, context?: object): Schema
Для вложенных схем reach
получит внутреннюю схему на основе предоставленного пути.
Для вложенных схем, которые необходимо разрешать динамически, вы можете указать value
и, при необходимости, объект context
.
import { reach } from 'yup' ;
let schema = object ( {
nested : object ( {
arr : array ( object ( { num : number ( ) . max ( 4 ) } ) ) ,
} ) ,
} ) ;
reach ( schema , 'nested.arr.num' ) ;
reach ( schema , 'nested.arr[].num' ) ;
reach ( schema , 'nested.arr[1].num' ) ;
reach ( schema , 'nested["arr"][1].num' ) ;
addMethod(schemaType: Schema, name: string, method: ()=> Schema): void
Добавляет новый метод к основным типам схем. Более дружественный и удобный метод для schemaType.prototype[name] = method
.
import { addMethod , date } from 'yup' ;
addMethod ( date , 'format' , function format ( formats , parseStrict ) {
return this . transform ( ( value , originalValue , ctx ) => {
if ( ctx . isType ( value ) ) return value ;
value = Moment ( originalValue , formats , parseStrict ) ;
return value . isValid ( ) ? value . toDate ( ) : new Date ( '' ) ;
} ) ;
} ) ;
Если вы хотите добавить метод ко ВСЕМ типам схем, расширьте абстрактный базовый класс: Schema
import { addMethod , Schema } from 'yup' ;
addMethod ( Schema , 'myMethod' , ... )
ref(path: string, options: { contextPrefix: string }): Ref
Создает ссылку на другое поле родственного или родственного потомка. Ссылки разрешаются во время проверки/приведения и поддерживаются, где указано. Ссылки оцениваются в правильном порядке, так что значение ref разрешается до поля, использующего ref (будьте осторожны с циклическими зависимостями!).
import { ref , object , string } from 'yup' ;
let schema = object ( {
baz : ref ( 'foo.bar' ) ,
foo : object ( {
bar : string ( ) ,
} ) ,
x : ref ( '$x' ) ,
} ) ;
schema . cast ( { foo : { bar : 'boom' } } , { context : { x : 5 } } ) ;
// => { baz: 'boom', x: 5, foo: { bar: 'boom' } }
lazy((value: any) => Schema): Lazy
Создает схему, которая оценивается во время проверки/приведения. Полезно для создания рекурсивной схемы, такой как деревья, для полиморфных полей и массивов.
ОСТОРОЖНОСТЬ! При определении схемы рекурсивного объекта «родитель-потомок» необходимо сбросить значение default()
для дочернего элемента до null
— в противном случае объект будет бесконечно вложен в себя при его приведении!
let node = object ( {
id : number ( ) ,
child : yup . lazy ( ( ) => node . default ( undefined ) ) ,
} ) ;
let renderable = yup . lazy ( ( value ) => {
switch ( typeof value ) {
case 'number' :
return number ( ) ;
case 'string' :
return string ( ) ;
default :
return mixed ( ) ;
}
} ) ;
let renderables = array ( ) . of ( renderable ) ;
ValidationError(errors: string | Array<string>, value: any, path: string)
Выбрасывается при неудачных проверках со следующими свойствами
name
: «Ошибка проверки»type
: конкретный тип теста или «имя» теста, который не прошёл.value
: значение поля, которое было протестировано;params
?: тестовые входные данные, такие как максимальное значение, регулярное выражение и т. д.;path
: строка, указывающая, где возникла ошибка. path
пуст на корневом уровне.errors
: массив сообщений об ошибкахinner
: в случае совокупных ошибок внутренний — это массив ValidationErrors
выброшенных ранее в цепочке проверки. Если для параметра abortEarly
установлено значение false
, вы можете проверить каждую возникшую ошибку; в качестве альтернативы errors
будут содержать все сообщения о каждой внутренней ошибке.Schema
Schema
— это абстрактный базовый класс, от которого наследуются все типы схем. Он предоставляет ряд базовых методов и свойств для всех других типов схем.
Примечание. Если вы не создаете собственный тип схемы, схему никогда не следует использовать напрямую. Для неизвестных/любых типов используйте
mixed()
Schema.clone(): Schema
Создает глубокую копию схемы. Клонирование используется внутри системы для возврата новой схемы при каждом изменении состояния схемы.
Schema.label(label: string): Schema
Переопределяет имя ключа, которое используется в сообщениях об ошибках.
Schema.meta(metadata: SchemaMetadata): Schema
Добавляет к объекту метаданных, полезный для хранения данных со схемой, которая не принадлежит самому объекту приведения.
Пользовательский интерфейс SchemaMetadata
можно определить путем слияния с интерфейсом CustomSchemaMetadata
. Начните с создания файла yup.d.ts
в вашем пакете и создания желаемого интерфейса CustomSchemaMetadata
:
// yup.d.ts
import 'yup' ;
declare module 'yup' {
// Define your desired `SchemaMetadata` interface by merging the
// `CustomSchemaMetadata` interface.
export interface CustomSchemaMetadata {
placeholderText ?: string ;
tooltipText ?: string ;
// …
}
}
Schema.describe(options?: ResolveOptions): SchemaDescription
Собирает сведения о схеме (например, мета-метки, метки и активные тесты) в сериализуемый объект описания.
let schema = object ( {
name : string ( ) . required ( ) ,
} ) ;
let description = schema . describe ( ) ;
Для схемы с динамическими компонентами (ссылками, ленивыми или условиями) для описания требуется больше контекста, чтобы точно вернуть описание схемы. В этих случаях предусмотрите options
import { ref , object , string , boolean } from 'yup' ;
let schema = object ( {
isBig : boolean ( ) ,
count : number ( ) . when ( 'isBig' , {
is : true ,
then : ( schema ) => schema . min ( 5 ) ,
otherwise : ( schema ) => schema . min ( 0 ) ,
} ) ,
} ) ;
schema . describe ( { value : { isBig : true } } ) ;
Ниже приведены типы описаний, которые немного отличаются в зависимости от типа схемы.
interface SchemaDescription {
type : string ;
label ?: string ;
meta : object | undefined ;
oneOf : unknown [ ] ;
notOneOf : unknown [ ] ;
default ?: unknown ;
nullable : boolean ;
optional : boolean ;
tests : Array < { name ?: string ; params : ExtraParams | undefined } > ;
// Present on object schema descriptions
fields : Record < string , SchemaFieldDescription > ;
// Present on array schema descriptions
innerType ?: SchemaFieldDescription ;
}
type SchemaFieldDescription =
| SchemaDescription
| SchemaRefDescription
| SchemaLazyDescription ;
interface SchemaRefDescription {
type : 'ref' ;
key : string ;
}
interface SchemaLazyDescription {
type : string ;
label ?: string ;
meta : object | undefined ;
}
Schema.concat(schema: Schema): Schema
Создает новый экземпляр схемы путем объединения двух схем. Объединять можно только схемы одного типа. concat
не является функцией «слияния» в том смысле, что все настройки из предоставленной схемы переопределяют настройки в базе, включая тип, наличие и возможность обнуления.
mixed < string > ( ) . defined ( ) . concat ( mixed < number > ( ) . nullable ( ) ) ;
// produces the equivalent to:
mixed < number > ( ) . defined ( ) . nullable ( ) ;
Schema.validate(value: any, options?: object): Promise<InferType<Schema>, ValidationError>
Возвращает результаты синтаксического анализа и проверяет введенное значение, возвращая проанализированное значение или выдавая ошибку. Этот метод является асинхронным и возвращает объект Promise, который выполняется со значением или отклонен с ошибкой ValidationError
.
value = await schema . validate ( { name : 'jimmy' , age : 24 } ) ;
Предоставьте options
для более конкретного управления поведением validate
.
interface Options {
// when true, parsing is skipped and the input is validated "as-is"
strict: boolean = false ;
// Throw on the first error or collect and return all
abortEarly: boolean = true ;
// Remove unspecified keys from objects
stripUnknown: boolean = false ;
// when `false` validations will be performed shallowly
recursive: boolean = true ;
// External values that can be provided to validations and conditionals
context ?: object ;
}
Schema.validateSync(value: any, options?: object): InferType<Schema>
Если возможно, выполняет проверки синхронно и возвращает результирующее значение или выдает ValidationError. Принимает все те же параметры, что и validate
.
Синхронная проверка работает только в том случае, если нет настроенных асинхронных тестов, например тестов, возвращающих обещание. Например, это будет работать:
let schema = number ( ) . test (
'is-42' ,
"this isn't the number i want" ,
( value ) => value != 42 ,
) ;
schema . validateSync ( 23 ) ; // throws ValidationError
однако это не будет:
let schema = number ( ) . test ( 'is-42' , "this isn't the number i want" , ( value ) =>
Promise . resolve ( value != 42 ) ,
) ;
schema . validateSync ( 42 ) ; // throws Error
Schema.validateAt(path: string, value: any, options?: object): Promise<InferType<Schema>, ValidationError>
Проверьте глубоко вложенный путь в схеме. Аналогично тому, как работает reach
, но в качестве объекта проверки используется полученная схема.
Примечание!
value
здесь является корневое значение относительно начальной схемы, а не значение во вложенном пути.
let schema = object ( {
foo : array ( ) . of (
object ( {
loose : boolean ( ) ,
bar : string ( ) . when ( 'loose' , {
is : true ,
otherwise : ( schema ) => schema . strict ( ) ,
} ) ,
} ) ,
) ,
} ) ;
let rootValue = {
foo : [ { bar : 1 } , { bar : 1 , loose : true } ] ,
} ;
await schema . validateAt ( 'foo[0].bar' , rootValue ) ; // => ValidationError: must be a string
await schema . validateAt ( 'foo[1].bar' , rootValue ) ; // => '1'
Schema.validateSyncAt(path: string, value: any, options?: object): InferType<Schema>
То же, что и validateAt
но синхронно.
Schema.isValid(value: any, options?: object): Promise<boolean>
Возвращает true
если переданное значение соответствует схеме. isValid
является асинхронным и возвращает объект Promise.
Принимает те же параметры, что и validate()
.
Schema.isValidSync(value: any, options?: object): boolean
Синхронно возвращает true
если переданное значение соответствует схеме.
Принимает те же параметры, что и validateSync()
, и имеет те же предостережения относительно асинхронных тестов.
Schema.cast(value: any, options = {}): InferType<Schema>
Пытается привести переданное значение к значению, соответствующему схеме. Например: '5'
будет преобразовано в 5
при использовании типа number()
. Неудачные приведения обычно возвращают null
, но могут также возвращать такие результаты, как NaN
и неожиданные строки.
Предоставьте options
для более конкретного управления поведением validate
.
interface CastOptions < TContext extends { } > {
// Remove undefined properties from objects
stripUnknown : boolean = false ;
// Throws a TypeError if casting doesn't produce a valid type
// note that the TS return type is inaccurate when this is `false`, use with caution
assert ?: boolean = true ;
// External values that used to resolve conditions and references
context ?: TContext ;
}
Schema.isType(value: any): value is InferType<Schema>
Запускает проверку типа переданного value
. Он возвращает true, если оно соответствует, но не приводит значение. Когда nullable()
установлен, null
считается допустимым значением типа. Вы должны использовать isType
для всех проверок типа схемы.
Schema.strict(enabled: boolean = false): Schema
Устанавливает для параметра strict
значение true
. Строгие схемы пропускают попытки приведения и преобразования, проверяя значение «как есть».
Schema.strip(enabled: boolean = true): Schema
Помечает схему, которую необходимо удалить из выходного объекта. Работает только как вложенная схема.
let schema = object ( {
useThis : number ( ) ,
notThis : string ( ) . strip ( ) ,
} ) ;
schema . cast ( { notThis : 'foo' , useThis : 4 } ) ; // => { useThis: 4 }
Схема с включенной strip
имеет предполагаемый тип never
, что позволяет удалить их из общего типа:
let schema = object ( {
useThis : number ( ) ,
notThis : string ( ) . strip ( ) ,
} ) ;
InferType < typeof schema > ; /*
{
useThis?: number | undefined
}
*/
Schema.withMutation(builder: (current: Schema) => void): void
Сначала юридически требуемая цитата Рича Хики:
Если в лесу упадет дерево, издаст ли оно звук?
Если чистая функция изменяет некоторые локальные данные, чтобы получить неизменяемое возвращаемое значение, нормально ли это?
withMutation
позволяет вам изменять схему на месте вместо поведения по умолчанию, которое клонирует перед каждым изменением. Обычно в этом нет необходимости, поскольку подавляющее большинство изменений схемы происходит во время первоначального объявления и происходит только один раз за время существования схемы, поэтому производительность не является проблемой. Однако определенные мутации происходят во время приведения/проверки (например, при использовании условной схемы when()
) или при создании экземпляра объекта схемы.
object ( )
. shape ( { key : string ( ) } )
. withMutation ( ( schema ) => {
return arrayOfObjectTests . forEach ( ( test ) => {
schema . test ( test ) ;
} ) ;
} ) ;
Schema.default(value: any): Schema
Устанавливает значение по умолчанию, которое будет использоваться, если значение undefined
. Значения по умолчанию создаются после выполнения преобразований, но до проверок, чтобы гарантировать, что указаны безопасные значения по умолчанию. Значение по умолчанию будет клонироваться при каждом использовании, что может повлечь за собой снижение производительности для объектов и массивов. Чтобы избежать этих накладных расходов, вы также можете передать функцию, которая возвращает новое значение по умолчанию. Обратите внимание, что null
считается отдельным непустым значением.
yup . string . default ( 'nothing' ) ;
yup . object . default ( { number : 5 } ) ; // object will be cloned every time a default is needed
yup . object . default ( ( ) => ( { number : 5 } ) ) ; // this is cheaper
yup . date . default ( ( ) => new Date ( ) ) ; // also helpful for defaults that change over time
Schema.getDefault(options?: object): Any
Получите ранее установленное значение по умолчанию. getDefault
разрешит любые условия, которые могут изменить значение по умолчанию. При необходимости передайте options
с context
(дополнительную информацию о context
см. в Schema.validate
).
Schema.nullable(message?: string | function): Schema
Указывает, что null
является допустимым значением для схемы. Без nullable()
null
рассматривается как другой тип и не проходит проверку Schema.isType()
.
let schema = number ( ) . nullable ( ) ;
schema . cast ( null ) ; // null
InferType < typeof schema > ; // number | null
Schema.nonNullable(message?: string | function): Schema
Противоположность nullable
удаляет null
из допустимых значений типа для схемы. По умолчанию схема не допускает значения NULL .
let schema = number ( ) . nonNullable ( ) ;
schema . cast ( null ) ; // TypeError
InferType < typeof schema > ; // number
Schema.defined(): Schema
Требуйте значение для схемы. Все значения полей, кроме undefined
соответствуют этому требованию.
let schema = string ( ) . defined ( ) ;
schema . cast ( undefined ) ; // TypeError
InferType < typeof schema > ; // string
Schema.optional(): Schema
Противоположность метода defined()
допускает undefined
значения для данного типа.
let schema = string ( ) . optional ( ) ;
schema . cast ( undefined ) ; // undefined
InferType < typeof schema > ; // string | undefined
Schema.required(message?: string | function): Schema
Отметьте схему как обязательную, которая не допустит undefined
или null
в качестве значения. required
сводит на нет эффекты вызова optional()
и nullable()
Осторожно!
string().required
) работает немного по-другому и дополнительно предотвращает пустые строковые значения (''
), когда это необходимо.
Schema.notRequired(): Schema
Отметьте схему как необязательную. Это ярлык для schema.nullable().optional()
;
Schema.typeError(message: string): Schema
Определите сообщение об ошибке для неудачных проверок типа. В аргументе message
можно использовать интерполяцию ${value}
и ${type}
.
Schema.oneOf(arrayOfValues: Array<any>, message?: string | function): Schema
: equals
Разрешить только значения из набора значений. Добавленные значения удаляются из любых значений notOneOf
, если они присутствуют. Интерполяцию ${values}
можно использовать в аргументе message
. Если указана ссылка или ссылки, интерполяцию ${resolved}
можно использовать в аргументе сообщения, чтобы получить разрешенные значения, которые были проверены во время проверки.
Обратите внимание, что undefined
не приводит к сбою этого валидатора, даже если undefined
не включен в arrayOfValues
. Если вы не хотите, чтобы undefined
было допустимым значением, вы можете использовать Schema.required
.
let schema = yup . mixed ( ) . oneOf ( [ 'jimmy' , 42 ] ) ;
await schema . isValid ( 42 ) ; // => true
await schema . isValid ( 'jimmy' ) ; // => true
await schema . isValid ( new Date ( ) ) ; // => false
Schema.notOneOf(arrayOfValues: Array<any>, message?: string | function)
Запретить значения из набора значений. Добавленные значения удаляются из значений oneOf
если они присутствуют. Интерполяцию ${values}
можно использовать в аргументе message
. Если указана ссылка или ссылки, интерполяцию ${resolved}
можно использовать в аргументе сообщения, чтобы получить разрешенные значения, которые были проверены во время проверки.
let schema = yup . mixed ( ) . notOneOf ( [ 'jimmy' , 42 ] ) ;
await schema . isValid ( 42 ) ; // => false
await schema . isValid ( new Date ( ) ) ; // => true
Schema.when(keys: string | string[], builder: object | (values: any[], schema) => Schema): Schema
Настройте схему на основе одноуровневых или одноуровневых дочерних полей. Вы можете предоставить литерал объекта, где ключом is
значение или функция сопоставления, then
предоставить истинную схему и/или otherwise
для условия сбоя.
is
строго сравниваются ( ===
). Если вы хотите использовать другую форму равенства, вы можете предоставить такую функцию: is: (value) => value == true
.
Вы также можете добавить к свойствам префикс $
, чтобы указать свойство, которое зависит от context
переданного функцией validate()
или cast
вместо входного значения.
when
условия аддитивны.
then
и otherwise
указываются функции (schema: Schema) => Schema
.
let schema = object ( {
isBig : boolean ( ) ,
count : number ( )
. when ( 'isBig' , {
is : true , // alternatively: (val) => val == true
then : ( schema ) => schema . min ( 5 ) ,
otherwise : ( schema ) => schema . min ( 0 ) ,
} )
. when ( '$other' , ( [ other ] , schema ) =>
other === 4 ? schema . max ( 6 ) : schema ,
) ,
} ) ;
await schema . validate ( value , { context : { other : 4 } } ) ;
Вы также можете указать более одного зависимого ключа, и в этом случае каждое значение будет распространяться в качестве аргумента.
let schema = object ( {
isSpecial : boolean ( ) ,
isBig : boolean ( ) ,
count : number ( ) . when ( [ 'isBig' , 'isSpecial' ] , {
is : true , // alternatively: (isBig, isSpecial) => isBig && isSpecial
then : ( schema ) => schema . min ( 5 ) ,
otherwise : ( schema ) => schema . min ( 0 ) ,
} ) ,
} ) ;
await schema . validate ( {
isBig : true ,
isSpecial : true ,
count : 10 ,
} ) ;
В качестве альтернативы вы можете предоставить функцию, которая возвращает схему, вызываемую с массивом значений для каждого предоставленного ключа текущей схемы.
let schema = yup . object ( {
isBig : yup . boolean ( ) ,
count : yup . number ( ) . when ( 'isBig' , ( [ isBig ] , schema ) => {
return isBig ? schema . min ( 5 ) : schema . min ( 0 ) ;
} ) ,
} ) ;
await schema . validate ( { isBig : false , count : 4 } ) ;
Schema.test(name: string, message: string | function | any, test: function): Schema
Добавляет тестовую функцию в цепочку проверки. Тесты запускаются после приведения любого объекта. Многие типы имеют встроенные тесты, но вы можете легко создавать собственные. Чтобы разрешить асинхронные пользовательские проверки, все тесты (или их отсутствие) выполняются асинхронно. Следствием этого является невозможность гарантировать порядок выполнения тестов.
Все тесты должны предоставлять name
, message
об ошибке и функцию проверки, которая должна возвращать true
если текущее value
допустимо, и false
, или же ValidationError
в противном случае. Чтобы сделать асинхронный тест, верните обещание, которое разрешает true
или false
, или ValidationError
.
В качестве аргумента message
вы можете указать строку, которая будет интерполировать определенные значения, если они указаны с использованием синтаксиса ${param}
. По умолчанию всем тестовым сообщениям передается значение path
, которое важно во вложенных схемах.
test
функция вызывается с текущим value
. Для более сложных проверок вы можете использовать альтернативную подпись, чтобы предоставить больше возможностей (см. ниже):
let jimmySchema = string ( ) . test (
'is-jimmy' ,
'${path} is not Jimmy' ,
( value , context ) => value === 'jimmy' ,
) ;
// or make it async by returning a promise
let asyncJimmySchema = string ( )
. label ( 'First name' )
. test (
'is-jimmy' ,
( { label } ) => ` ${ label } is not Jimmy` , // a message can also be a function
async ( value , testContext ) =>
( await fetch ( '/is-jimmy/' + value ) ) . responseText === 'true' ,
) ;
await schema . isValid ( 'jimmy' ) ; // => true
await schema . isValid ( 'john' ) ; // => false
Тестовые функции вызываются со специальным значением контекста в качестве второго аргумента, который предоставляет некоторые полезные метаданные и функции. Для функций без стрелок тестовый контекст также устанавливается как функция this
. Будьте осторожны: если вы получите к нему доступ через this
он не будет работать в функции стрелки.
testContext.path
: строковый путь текущей проверки.testContext.schema
: разрешенный объект схемы, для которого выполняется тест.testContext.options
: объект options
, который вызывается validate() или isValid().testContext.parent
: в случае вложенной схемы это значение родительского объекта.testContext.originalValue
: исходное значение, которое тестируется.testContext.createError(Object: { path: String, message: String, params: Object })
: создаёт и возвращает ошибку проверки. Полезно для динамической установки path
, params
или, что более вероятно, message
об ошибке. Если какой-либо параметр опущен, будет использоваться текущий путь или сообщение по умолчанию. Schema.test(options: object): Schema
Альтернативная test(..)
подпись. options
— это объект, содержащий некоторые из следующих параметров:
Options = {
// unique name identifying the test
name : string ;
// test function, determines schema validity
test: ( value : any ) => boolean ;
// the validation error message
message: string ;
// values passed to message for interpolation
params: ? object ;
// mark the test as exclusive, meaning only one test of the same name can be active at once
exclusive: boolean = false ;
}
В случае смешивания эксклюзивных и неэксклюзивных тестов используется следующая логика. Если неэксклюзивный тест добавляется в схему с эксклюзивным тестом с тем же именем, эксклюзивный тест удаляется, и дальнейшие тесты с тем же именем будут группироваться.
Если в схему с неэксклюзивными одноимёнными тестами добавляется эксклюзивный тест, предыдущие тесты удаляются, а последующие одноимённые тесты заменяют друг друга.
let max = 64 ;
let schema = yup . string ( ) . test ( {
name : 'max' ,
exclusive : true ,
params : { max } ,
message : '${path} must be less than ${max} characters' ,
test : ( value ) => value == null || value . length <= max ,
} ) ;
Schema.transform((currentValue: any, originalValue: any) => any): Schema
Добавляет преобразование в цепочку преобразований. Преобразования занимают центральное место в процессе приведения, преобразования по умолчанию для каждого типа приводят значения к определенному типу (что проверено isType()
). преобразования запускаются перед проверками и применяются только в том случае, если схема не помечена как strict
(по умолчанию). Некоторые типы имеют встроенные трансформации.
Преобразования полезны для произвольного изменения способа приведения объекта, однако следует позаботиться о том, чтобы не изменить переданное значение. Преобразования выполняются последовательно, поэтому каждое value
представляет текущее состояние приведения. Вы можете использовать параметр originalValue
, если вам нужно работать с необработанным начальным значением.
let schema = string ( ) . transform ( ( value , originalValue ) => {
return this . isType ( value ) && value !== null ? value . toUpperCase ( ) : value ;
} ) ;
schema . cast ( 'jimmy' ) ; // => 'JIMMY'
Каждый тип будет выполнять базовое приведение значений к нужному типу, но иногда вам может потребоваться настроить или уточнить поведение по умолчанию. Например, если вы хотите использовать стратегию анализа даты, отличную от стратегии по умолчанию, вы можете сделать это с помощью преобразования.
module . exports = function ( formats = 'MMM dd, yyyy' ) {
return date ( ) . transform ( ( value , originalValue , context ) => {
// check to see if the previous transform already parsed the date
if ( context . isType ( value ) ) return value ;
// the default coercion failed so let's try it with Moment.js instead
value = Moment ( originalValue , formats ) ;
// if it's valid return the date object, otherwise return an `InvalidDate`
return value . isValid ( ) ? value . toDate ( ) : new Date ( '' ) ;
} ) ;
} ;
Создает схему, соответствующую всем типам или только тем, которые вы настраиваете. Наследует от Schema
. Смешанные типы по умолчанию расширяют {}
вместо any
или unknown
. Это связано с тем, что в TypeScript {}
означает все, что не является null
или undefined
, что да, обрабатывается отдельно.
import { mixed , InferType } from 'yup' ;
let schema = mixed ( ) . nullable ( ) ;
schema . validateSync ( 'string' ) ; // 'string';
schema . validateSync ( 1 ) ; // 1;
schema . validateSync ( new Date ( ) ) ; // Date;
InferType < typeof schema > ; // {} | undefined
InferType < typeof schema . nullable ( ) . defined ( ) > ; // {} | null
Пользовательские типы могут быть реализованы путем передачи функции check
типа. Это также сузит тип TypeScript для схемы.
import { mixed , InferType } from 'yup' ;
let objectIdSchema = yup
. mixed ( ( input ) : input is ObjectId => input instanceof ObjectId )
. transform ( ( value : any , input , ctx ) => {
if ( ctx . isType ( value ) ) return value ;
return new ObjectId ( value ) ;
} ) ;
await objectIdSchema . validate ( ObjectId ( '507f1f77bcf86cd799439011' ) ) ; // ObjectId("507f1f77bcf86cd799439011")
await objectIdSchema . validate ( '507f1f77bcf86cd799439011' ) ; // ObjectId("507f1f77bcf86cd799439011")
InferType < typeof objectIdSchema > ; // ObjectId
Определите строковую схему. Наследует от Schema
.
let schema = yup . string ( ) ;
await schema . isValid ( 'hello' ) ; // => true
По умолчанию логика cast
string
заключается в вызове toString
для значения, если оно существует.
пустые значения не приводятся (используйте ensure()
для приведения пустых значений к пустым строкам).
Неудачные приведения возвращают входное значение.
string.required(message?: string | function): Schema
То же, что требуется для схемы mixed()
, за исключением того, что пустые строки также считаются «отсутствующими» значениями.
string.length(limit: number | Ref, message?: string | function): Schema
Установите необходимую длину строкового значения. Интерполяцию ${length}
можно использовать в аргументе message
.
string.min(limit: number | Ref, message?: string | function): Schema
Установите ограничение минимальной длины для строкового значения. Интерполяцию ${min}
можно использовать в аргументе message
.
string.max(limit: number | Ref, message?: string | function): Schema
Установите ограничение максимальной длины для строкового значения. Интерполяцию ${max}
можно использовать в аргументе message
.
string.matches(regex: Regex, message?: string | function): Schema
Укажите произвольное regex
для сопоставления значения.
let schema = string ( ) . matches ( / (hi|bye) / ) ;
await schema . isValid ( 'hi' ) ; // => true
await schema . isValid ( 'nope' ) ; // => false
string.matches(regex: Regex, options: { message: string, excludeEmptyString: bool }): Schema
Альтернативная подпись для string.matches
с объектом параметров. excludeEmptyString
, если установлено значение true, замыкает проверку регулярного выражения, когда значение представляет собой пустую строку, что позволяет избежать отсутствия совпадений без усложнения регулярного выражения.
let schema = string ( ) . matches ( / (hi|bye) / , { excludeEmptyString : true } ) ;
await schema . isValid ( '' ) ; // => true
string.email(message?: string | function): Schema
Проверяет значение как адрес электронной почты, используя то же регулярное выражение, определенное в спецификации HTML.
ВНИМАНИЕ: проверить адреса электронной почты с помощью простого кода практически невозможно. Разные клиенты и серверы принимают разные вещи, и многие из них расходятся с различными спецификациями, определяющими «действительные» электронные письма. ЕДИНСТВЕННЫЙ реальный способ подтвердить адрес электронной почты — отправить на него проверочное письмо и убедиться, что пользователь его получил. Имея это в виду, да, вы выбираете относительно простое регулярное выражение, которое не охватывает все случаи, но соответствует поведению проверки ввода браузера, поскольку HTML-формы являются распространенным вариантом использования для да.
Если у вас есть более конкретные потребности, переопределите метод электронной почты своей собственной логикой или регулярным выражением:
yup . addMethod ( yup . string , 'email' , function validateEmail ( message ) {
return this . matches ( myEmailRegex , {
message ,
name : 'email' ,
excludeEmptyString : true ,
} ) ;
} ) ;
string.url(message?: string | function): Schema
Проверяет значение как действительный URL-адрес с помощью регулярного выражения.
string.uuid(message?: string | function): Schema
Проверяет значение как действительный UUID с помощью регулярного выражения.
string.datetime(options?: {message?: string | function, allowOffset?: boolean, precision?: number})
Проверяет значение как дату и время ISO с помощью регулярного выражения. По умолчанию используется проверка UTC; Смещения часовых поясов не допускаются (см. options.allowOffset
).
В отличие от .date()
, datetime
не преобразует строку в объект Date
. datetime
также обеспечивает большую настройку требуемого формата строки datetime, чем date
.
options.allowOffset
: разрешить смещение часового пояса. False требует часового пояса UTC «Z». (по умолчанию: false) options.precision
: Требует определенной точности до доли секунды для даты. (по умолчанию: ноль — любая (или никакая) точность до доли секунды)
string.datetime(message?: string | function)
Альтернативная подпись для string.datetime
, которую можно использовать, когда вам не нужно передавать другие параметры, кроме message
.
string.ensure(): Schema
Преобразует undefined
и null
значения в пустую строку, а также устанавливает пустую строку default
.
string.trim(message?: string | function): Schema
Преобразует строковые значения, удаляя начальные и конечные пробелы. Если установлен strict()
он будет проверять только то, что значение обрезано.
string.lowercase(message?: string | function): Schema
Преобразует строковое значение в нижний регистр. Если установлен strict()
он будет проверять только то, что значение написано в нижнем регистре.
string.uppercase(message?: string | function): Schema
Преобразует строковое значение в верхний регистр. Если установлен strict()
он будет проверять только то, что значение указано в верхнем регистре.
Дайте определение числовой схемы. Наследует от Schema
.
let schema = yup . number ( ) ;
await schema . isValid ( 10 ) ; // => true
Логика cast
number
по умолчанию: parseFloat
.
Неудачные приведения возвращают NaN
.
number.min(limit: number | Ref, message?: string | function): Schema
Установите минимально допустимое значение. Интерполяцию ${min}
можно использовать в аргументе message
.
number.max(limit: number | Ref, message?: string | function): Schema
Установите максимально допустимое значение. Интерполяцию ${max}
можно использовать в аргументе message
.
number.lessThan(max: number | Ref, message?: string | function): Schema
Значение должно быть меньше max
. Интерполяцию ${less}
можно использовать в аргументе message
.
number.moreThan(min: number | Ref, message?: string | function): Schema
Значение должно быть строго больше min
. Интерполяцию ${more}
можно использовать в аргументе message
.
number.positive(message?: string | function): Schema
Значение должно быть положительным числом.
number.negative(message?: string | function): Schema
Значение должно быть отрицательным числом.
number.integer(message?: string | function): Schema
Проверяет, что число является целым.
number.truncate(): Schema
Преобразование, которое приводит значение к целому числу путем удаления цифр справа от десятичной точки.
number.round(type: 'floor' | 'ceil' | 'trunc' | 'round' = 'round'): Schema
Регулирует значение с помощью указанного метода Math
(по умолчанию «округление»).
Определите логическую схему. Наследует от Schema
.
let schema = yup . boolean ( ) ;
await schema . isValid ( true ) ; // => true
Определите схему даты. По умолчанию строки даты ISO будут анализироваться правильно. Более надежные варианты анализа см. в расширенных типах схемы в конце файла readme. Наследует от Schema
.
let schema = yup . date ( ) ;
await schema . isValid ( new Date ( ) ) ; // => true
Логика cast
date
по умолчанию заключается в передаче значения конструктору Date
, в противном случае он попытается проанализировать дату как строку даты ISO.
Если вы не хотите, чтобы строки ISO приводились к объекту
Date
, используйте вместо этого.datetime()
.
Неудачные приведения возвращают неверную дату.
date.min(limit: Date | string | Ref, message?: string | function): Schema
Установите минимальную разрешенную дату. Если указана строка, она сначала попытается привести дату и использовать результат в качестве ограничения.
date.max(limit: Date | string | Ref, message?: string | function): Schema
Установите максимально допустимую дату. Если указана строка, она сначала попытается привести ее к дате и использовать результат в качестве ограничения.
Определите схему массива. Массивы могут быть типизированными или нет. При указании типа элемента к элементам также будут применяться cast
и isValid
. Параметры, переданные в isValid
также передаются дочерним схемам.
Наследует от Schema
.
let schema = yup . array ( ) . of ( yup . number ( ) . min ( 2 ) ) ;
await schema . isValid ( [ 2 , 3 ] ) ; // => true
await schema . isValid ( [ 1 , - 24 ] ) ; // => false
schema . cast ( [ '2' , '3' ] ) ; // => [2, 3]
Для удобства вы также можете передать схему подтипа конструктору массива.
array ( ) . of ( yup . number ( ) ) ;
// or
array ( yup . number ( ) ) ;
Массивы не имеют поведения приведения по умолчанию.
array.of(type: Schema): this
Укажите схему элементов массива. of()
является необязательным, и если его опустить, схема массива не будет проверять его содержимое.
array.json(): this
Попытайтесь проанализировать значения входной строки как JSON, используя JSON.parse
.
array.length(length: number | Ref, message?: string | function): this
Установите определенное требование к длине массива. Интерполяцию ${length}
можно использовать в аргументе message
.
array.min(limit: number | Ref, message?: string | function): this
Установите ограничение минимальной длины для массива. Интерполяцию ${min}
можно использовать в аргументе message
.
array.max(limit: number | Ref, message?: string | function): this
Установите максимальную длину массива. Интерполяцию ${max}
можно использовать в аргументе message
.
array.ensure(): this
Гарантирует, что значение является массивом, устанавливая значение по умолчанию на []
и также преобразуя значения null
и undefined
значения в пустой массив. Любое непустое значение, не являющееся массивом, будет заключено в массив.
array ( ) . ensure ( ) . cast ( null ) ; // => []
array ( ) . ensure ( ) . cast ( 1 ) ; // => [1]
array ( ) . ensure ( ) . cast ( [ 1 ] ) ; // => [1]
array.compact(rejector: (value) => boolean): Schema
Удаляет ложные значения из массива. Предоставление функции отклонения позволяет вам самостоятельно указать критерии отклонения.
array ( ) . compact ( ) . cast ( [ '' , 1 , 0 , 4 , false , null ] ) ; // => [1, 4]
array ( )
. compact ( function ( v ) {
return v == null ;
} )
. cast ( [ '' , 1 , 0 , 4 , false , null ] ) ; // => ['', 1, 0, 4, false]
Кортежи — это массивы фиксированной длины, где каждый элемент имеет отдельный тип.
Наследует от Schema
.
import { tuple , string , number , InferType } from 'yup' ;
let schema = tuple ( [
string ( ) . label ( 'name' ) ,
number ( ) . label ( 'age' ) . positive ( ) . integer ( ) ,
] ) ;
await schema . validate ( [ 'James' , 3 ] ) ; // ['James', 3]
await schema . validate ( [ 'James' , - 24 ] ) ; // => ValidationError: age must be a positive number
InferType < typeof schema > // [string, number] | undefined
Кортежи не имеют поведения приведения по умолчанию.
Определите схему объекта. Параметры, переданные в isValid
также передаются дочерним схемам. Наследует от Schema
.
yup . object ( {
name : string ( ) . required ( ) ,
age : number ( ) . required ( ) . positive ( ) . integer ( ) ,
email : string ( ) . email ( ) ,
website : string ( ) . url ( ) ,
} ) ;
к схеме объекта не применяются никакие преобразования по умолчанию.
Схема объекта поставляется с уже установленным значением по умолчанию, которое «строит» форму объекта и устанавливает любые значения по умолчанию для полей:
let schema = object ( {
name : string ( ) . default ( '' ) ,
} ) ;
schema . default ( ) ; // -> { name: '' }
Это может быть немного удивительно, но обычно полезно, поскольку позволяет большой вложенной схеме создавать значения по умолчанию, которые заполняют всю фигуру, а не только корневой объект. Есть одна ошибка! хотя. Для схемы вложенных объектов, которая является необязательной, но включает необязательные поля, может произойти неожиданный сбой:
let schema = object ( {
id : string ( ) . required ( ) ,
names : object ( {
first : string ( ) . required ( ) ,
} ) ,
} ) ;
schema . isValid ( { id : 1 } ) ; // false! names.first is required
Это связано с тем, что да преобразует входной объект перед запуском проверки, которая выдаст:
{ id: '1', names: { first: undefined }}
На этапе проверки names
существуют и проверяются, обнаруживая, names.first
отсутствуют. Если вы хотите избежать такого поведения, выполните одно из следующих действий:
names.default(undefined)
names.nullable().default(null)
object.shape(fields: object, noSortEdges?: Array<[string, string]>): Schema
Определите ключи объекта и схемы для указанных ключей.
Обратите внимание, что вы можете связать метод shape
, который действует как Object.assign
.
object ( {
a : string ( ) ,
b : number ( ) ,
} ) . shape ( {
b : string ( ) ,
c : number ( ) ,
} ) ;
будет точно так же, как:
object ( {
a : string ( ) ,
b : string ( ) ,
c : number ( ) ,
} ) ;
object.json(): this
Попытайтесь проанализировать значения входной строки как JSON, используя JSON.parse
.
object.concat(schemaB: ObjectSchema): ObjectSchema
Создает схему объекта, применяя все настройки и поля из schemaB
к базовой, создавая новую схему. Форма объекта частично объединяется с общими полями из schemaB
имеющими приоритет над базовыми полями.
object.pick(keys: string[]): Schema
Создайте новую схему из подмножества полей оригинала.
let person = object ( {
age : number ( ) . default ( 30 ) . required ( ) ,
name : string ( ) . default ( 'pat' ) . required ( ) ,
color : string ( ) . default ( 'red' ) . required ( ) ,
} ) ;
let nameAndAge = person . pick ( [ 'name' , 'age' ] ) ;
nameAndAge . getDefault ( ) ; // => { age: 30, name: 'pat'}
object.omit(keys: string[]): Schema
Создайте новую схему с опущенными полями.
let person = object ( {
age : number ( ) . default ( 30 ) . required ( ) ,
name : string ( ) . default ( 'pat' ) . required ( ) ,
color : string ( ) . default ( 'red' ) . required ( ) ,
} ) ;
let nameAndAge = person . omit ( [ 'color' ] ) ;
nameAndAge . getDefault ( ) ; // => { age: 30, name: 'pat'}
object.from(fromKey: string, toKey: string, alias: boolean = false): this
Преобразует указанный ключ в новый ключ. Если alias
имеет true
, старый ключ останется.
let schema = object ( {
myProp : mixed ( ) ,
Other : mixed ( ) ,
} )
. from ( 'prop' , 'myProp' )
. from ( 'other' , 'Other' , true ) ;
schema . cast ( { prop : 5 , other : 6 } ) ; // => { myProp: 5, other: 6, Other: 6 }
object.noUnknown(onlyKnownKeys: boolean = true, message?: string | function): Schema
Убедитесь, что значение объекта содержит только ключи, указанные в shape
, передайте false
в качестве первого аргумента, чтобы отключить проверку. Ограничение ключей известными также включает опцию stripUnknown
, если не в строгом режиме.
object.camelCase(): Schema
Преобразует все ключи объекта в CamelCase.
object.constantCase(): Schema
Преобразует все ключи объекта в CONSTANT_CASE.