Yup ist ein Schema-Builder für die Analyse und Validierung von Laufzeitwerten. Definieren Sie ein Schema, transformieren Sie einen übereinstimmenden Wert, bestätigen Sie die Form eines vorhandenen Werts oder beides. Ja, Schemata sind äußerst ausdrucksstark und ermöglichen die Modellierung komplexer, voneinander abhängiger Validierungen oder Wertetransformationen.
Sie sehen sich Dokumente für Version 1.0.0 von Yup an. Dokumente vor Version 1 sind verfügbar: hier
Killer-Features :
Schemata bestehen aus Parsing-Aktionen (Transformationen) sowie Aussagen (Tests) über den Eingabewert. Validieren Sie einen Eingabewert, um ihn zu analysieren und den konfigurierten Satz von Behauptungen auszuführen. Verketten Sie Methoden, um ein Schema zu erstellen.
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
}*/
Verwenden Sie ein Schema, um einen Eingabewert in den richtigen Typ zu zwingen oder „umzuwandeln“ und diesen Wert optional in konkretere und spezifischere Werte umzuwandeln, ohne weitere Aussagen zu treffen.
// 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 }
Wissen Sie, dass Ihr Eingabewert bereits analysiert wurde? Sie können eine Eingabe „streng“ validieren und den Aufwand für die Ausführung der Parsing-Logik vermeiden.
// 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
Alias: 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
Schemadefinitionen bestehen aus Parsing-„Transformationen“, die Eingaben in die gewünschte Form und den gewünschten Typ manipulieren, sowie „Tests“, die Aussagen über analysierte Daten treffen. Schema speichert auch eine Reihe von „Metadaten“, Details über das Schema selbst, die zur Verbesserung von Fehlermeldungen, zum Erstellen von Tools, die Schemata dynamisch nutzen, oder zur Serialisierung von Schemata in ein anderes Format verwendet werden können.
Um größtmögliche Flexibilität zu gewährleisten, ermöglicht Yup die getrennte Ausführung von Parsing und Assertions, um spezifischen Anforderungen gerecht zu werden
Jeder integrierte Typ implementiert die grundlegende Typanalyse, was beim Parsen serialisierter Daten wie JSON nützlich ist. Darüber hinaus implementieren Typen typspezifische Transformationen, die aktiviert werden können.
let num = number ( ) . cast ( '1' ) ; // 1
let obj = object ( {
firstName : string ( ) . lowercase ( ) . trim ( ) ,
} )
. json ( )
. camelCase ( )
. cast ( '{"first_name": "jAnE "}' ) ; // { firstName: 'jane' }
Benutzerdefinierte Transformationen können hinzugefügt werden
let reversedString = string ( )
. transform ( ( currentValue ) => currentValue . split ( '' ) . reverse ( ) . join ( '' ) )
. cast ( 'dlrow olleh' ) ; // "hello world"
Transformationen bilden eine „Pipeline“, in der der Wert einer vorherigen Transformation in die nächste weitergeleitet wird. Wenn ein Eingabewert undefined
ist, wendet yup den Schemastandard an, sofern dieser konfiguriert ist.
Achtung! Es kann nicht garantiert werden, dass Werte in Transformationsfunktionen gültige Typen sind. Frühere Transformationen sind möglicherweise fehlgeschlagen. Beispielsweise kann eine Zahlentransformation den Eingabewert
NaN
oder eine Zahl empfangen.
Ja, das Schema führt „Tests“ über Eingabewerte durch. Tests bestätigen, dass Eingaben bestimmten Kriterien entsprechen. Tests unterscheiden sich von Transformationen dadurch, dass sie die Eingabe (oder deren Typ) nicht ändern oder verändern und normalerweise für Prüfungen reserviert sind, die sich nur schwer oder gar nicht in statischen Typen darstellen lassen.
string ( )
. min ( 3 , 'must be at least 3 characters long' )
. email ( 'must be a valid email' )
. validate ( 'no' ) ; // ValidationError
Wie bei Transformationen können Tests im Handumdrehen angepasst werden
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"
Achtung: Im Gegensatz zu Transformationen ist
value
in einem benutzerdefinierten Test garantiert vom richtigen Typ (in diesem Fall eine optionale Zeichenfolge). Abhängig von Ihrem Schema kann es immer nochundefined
odernull
sein. In diesen Fällen möchten Sie möglicherweisetrue
für fehlende Werte zurückgeben, es sei denn, Ihre Transformation macht präsenzbezogene Behauptungen. Die TestoptionskipAbsent
erledigt dies für Sie, wenn sie gesetzt ist.
Im einfachsten Fall gibt eine Testfunktion true
oder false
zurück, je nachdem, ob die Prüfung erfolgreich war. Im Falle eines fehlgeschlagenen Tests gibt yup einen ValidationError
mit Ihrer (oder der Standard-)Nachricht für diesen Test aus. ValidationErrors enthalten auch eine Reihe anderer Metadaten über den Test, einschließlich seines Namens, der Argumente (falls vorhanden), mit denen er aufgerufen wurde, und im Falle einer verschachtelten Validierung den Pfad zum fehlgeschlagenen Feld.
Fehlermeldungen können auch spontan erstellt werden, um anzupassen, wie das Schema fehlschlägt.
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' } )
Schemata sind unveränderlich, jeder Methodenaufruf gibt ein neues Schemaobjekt zurück. Verwenden Sie sie wieder und geben Sie sie weiter, ohne befürchten zu müssen, dass eine andere Instanz mutiert.
let optionalString = string ( ) . optional ( ) ;
let definedString = optionalString . defined ( ) ;
let value = undefined ;
optionalString . isValid ( value ) ; // true
definedString . isValid ( value ) ; // false
Ja, Schemas erzeugen statische TypeScript-Schnittstellen. Verwenden Sie InferType
, um diese Schnittstelle zu extrahieren:
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
}
Der Standardwert eines Schemas wird verwendet, wenn die Umwandlung einen undefined
Ausgabewert erzeugt. Aus diesem Grund wirkt sich das Festlegen eines Standardwerts auf den Ausgabetyp des Schemas aus und markiert es im Wesentlichen als „definiert()“.
import { string } from 'yup' ;
let value : string = string ( ) . default ( 'hi' ) . validate ( undefined ) ;
// vs
let value : string | undefined = string ( ) . validate ( undefined ) ;
In einigen Fällen ist bereits ein TypeScript-Typ vorhanden und Sie möchten sicherstellen, dass Ihr Schema einen kompatiblen Typ erzeugt:
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 ( ) ,
} ) ;
Sie können das Interface-Merging-Verhalten von TypeScript verwenden, um die Schematypen bei Bedarf zu erweitern. Typerweiterungen sollten in einer „ambient“-Typdefinitionsdatei wie Ihrem globals.d.ts
enthalten sein. Denken Sie daran, den Typ yup in Ihrem Anwendungscode tatsächlich zu erweitern!
Achtung! Das Zusammenführen funktioniert nur, wenn die Typdefinition genau gleich ist, einschließlich Generika. Konsultieren Sie den YUP-Quellcode für jeden Typ, um sicherzustellen, dass Sie ihn richtig definieren
// 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~~~~'
Damit die Typinferenz funktioniert, muss die Compileroption strictNullChecks
aktiviert sein.
Wir empfehlen außerdem, strictFunctionTypes
auf false
zu setzen, um funktional bessere Typen zu erhalten. Ja, dies verringert die allgemeine Solidität, TypeScript deaktiviert diese Prüfung jedoch bereits für Methoden und Konstruktoren (Hinweis aus TS-Dokumenten):
Während der Entwicklung dieser Funktion haben wir eine große Anzahl von Natur aus unsicherer Klassenhierarchien entdeckt, darunter einige im DOM. Aus diesem Grund gilt die Einstellung nur für Funktionen, die in Funktionssyntax geschrieben sind, nicht für Funktionen, die in Methodensyntax geschrieben sind:
Ihr Umfang wird variieren, aber wir haben festgestellt, dass diese Prüfung viele echte Fehler nicht verhindert und gleichzeitig die Menge der mühsamen expliziten Typumwandlung in Apps erhöht.
Standardfehlermeldungen können angepasst werden, wenn keine Meldung mit einem Validierungstest bereitgestellt wird. Wenn im benutzerdefinierten Wörterbuch eine Nachricht fehlt, wird als Fehlermeldung standardmäßig die von Yup angezeigt.
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']
}
Wenn Sie mehrsprachige Unterstützung benötigen, sind Sie bei yup genau richtig. Die Funktion setLocale
akzeptiert Funktionen, mit denen Fehlerobjekte mit Übersetzungsschlüsseln und -werten generiert werden können. Diese können in Ihre bevorzugte i18n-Bibliothek eingespeist werden.
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
Der Modulexport.
// 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
Bei verschachtelten Schemata ruft reach
ein inneres Schema basierend auf dem angegebenen Pfad ab.
Für verschachtelte Schemata, die dynamisch aufgelöst werden müssen, können Sie einen value
und optional ein context
bereitstellen.
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
Fügt den Kernschematypen eine neue Methode hinzu. Eine benutzerfreundlichere praktische Methode für 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 ( '' ) ;
} ) ;
} ) ;
Wenn Sie ALLEN Schematypen eine Methode hinzufügen möchten, erweitern Sie die abstrakte Basisklasse: Schema
import { addMethod , Schema } from 'yup' ;
addMethod ( Schema , 'myMethod' , ... )
ref(path: string, options: { contextPrefix: string }): Ref
Erstellt einen Verweis auf ein anderes gleichrangiges oder gleichrangiges Nachkommenfeld. Refs werden zum Zeitpunkt der Validierung/Umwandlung aufgelöst und unterstützt, sofern angegeben. Refs werden in der richtigen Reihenfolge ausgewertet, sodass der Ref-Wert vor dem Feld aufgelöst wird, das den Ref verwendet (Achten Sie auf zirkuläre Abhängigkeiten!).
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
Erstellt ein Schema, das zum Zeitpunkt der Validierung/Umsetzung ausgewertet wird. Nützlich zum Erstellen rekursiver Schemata wie Bäume, für polymorphe Felder und Arrays.
VORSICHT! Wenn Sie ein rekursives Eltern-Kind-Objektschema definieren, möchten Sie default()
für das untergeordnete Objekt auf null
zurücksetzen – andernfalls verschachtelt sich das Objekt unendlich, wenn Sie es umwandeln!
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)
Wird bei fehlgeschlagenen Validierungen mit den folgenden Eigenschaften ausgelöst
name
: „ValidationError“type
: der spezifische Testtyp oder Test-„Name“, der fehlgeschlagen ist.value
: Der Feldwert, der getestet wurde;params
?: Die Testeingaben, wie z. B. Maximalwert, Regex usw.;path
: eine Zeichenfolge, die angibt, wo der Fehler aufgetreten ist. path
ist auf der Stammebene leer.errors
: Array von Fehlermeldungeninner
: Im Fall von aggregierten Fehlern ist inner ein Array von ValidationErrors
die früher in der Validierungskette ausgelöst werden. Wenn die Option „ abortEarly
auf false
gesetzt ist, können Sie hier jeden ausgegebenen Fehler überprüfen. Alternativ enthalten errors
alle Meldungen von jedem inneren Fehler.Schema
Schema
ist die abstrakte Basisklasse, von der alle Schematypen erben. Es stellt eine Reihe von Basismethoden und Eigenschaften für alle anderen Schematypen bereit.
Hinweis: Sofern Sie keinen benutzerdefinierten Schematyp erstellen, sollte Schema niemals direkt verwendet werden. Für unbekannte/beliebige Typen verwenden Sie
mixed()
Schema.clone(): Schema
Erstellt eine tiefe Kopie des Schemas. Clone wird intern verwendet, um bei jeder Schemastatusänderung ein neues Schema zurückzugeben.
Schema.label(label: string): Schema
Überschreibt den Schlüsselnamen, der in Fehlermeldungen verwendet wird.
Schema.meta(metadata: SchemaMetadata): Schema
Fügt einem Metadatenobjekt hinzu, was zum Speichern von Daten mit einem Schema nützlich ist, das nicht zum Cast-Objekt selbst gehört.
Eine benutzerdefinierte SchemaMetadata
Schnittstelle kann durch Zusammenführen mit der CustomSchemaMetadata
-Schnittstelle definiert werden. Erstellen Sie zunächst eine yup.d.ts
Datei in Ihrem Paket und erstellen Sie die gewünschte CustomSchemaMetadata
Schnittstelle:
// 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
Sammelt Schemadetails (wie Meta, Labels und aktive Tests) in einem serialisierbaren Beschreibungsobjekt.
let schema = object ( {
name : string ( ) . required ( ) ,
} ) ;
let description = schema . describe ( ) ;
Bei Schemas mit dynamischen Komponenten (Referenzen, Lazy oder Bedingungen) erfordert „beschreiben“ mehr Kontext, um die Schemabeschreibung genau zurückzugeben. Stellen Sie in diesen Fällen options
bereit
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 } } ) ;
Und unten sind die Beschreibungstypen aufgeführt, die sich je nach Schematyp etwas unterscheiden.
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
Erstellt eine neue Instanz des Schemas durch die Kombination zweier Schemas. Es können nur Schemata desselben Typs verkettet werden. concat
ist keine „Merge“-Funktion in dem Sinne, dass alle Einstellungen aus dem bereitgestellten Schema diejenigen in der Basis überschreiben, einschließlich Typ, Präsenz und NULL-Zulässigkeit.
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>
Gibt die Analyse zurück und validiert einen Eingabewert, gibt den analysierten Wert zurück oder löst einen Fehler aus. Diese Methode ist asynchron und gibt ein Promise-Objekt zurück, das mit dem Wert erfüllt oder mit einem ValidationError
abgelehnt wird.
value = await schema . validate ( { name : 'jimmy' , age : 24 } ) ;
Stellen Sie options
bereit, um das Verhalten von validate
genauer zu steuern.
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>
Führt Validierungen nach Möglichkeit synchron aus und gibt den resultierenden Wert zurück oder löst einen ValidationError aus. Akzeptiert alle gleichen Optionen wie validate
.
Die synchrone Validierung funktioniert nur, wenn keine asynchronen Tests konfiguriert sind, z. B. Tests, die ein Versprechen zurückgeben. Das wird zum Beispiel funktionieren:
let schema = number ( ) . test (
'is-42' ,
"this isn't the number i want" ,
( value ) => value != 42 ,
) ;
schema . validateSync ( 23 ) ; // throws ValidationError
Dies wird jedoch nicht:
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>
Validieren Sie einen tief verschachtelten Pfad innerhalb des Schemas. Ähnlich wie reach
, verwendet jedoch das resultierende Schema als Betreff für die Validierung.
Notiz! Der
value
hier ist der Stammwert relativ zum Startschema, nicht der Wert am verschachtelten Pfad.
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>
Das Gleiche wie validateAt
, jedoch synchron.
Schema.isValid(value: any, options?: object): Promise<boolean>
Gibt true
zurück, wenn der übergebene Wert mit dem Schema übereinstimmt. isValid
ist asynchron und gibt ein Promise-Objekt zurück.
Nimmt die gleichen Optionen wie validate()
an.
Schema.isValidSync(value: any, options?: object): boolean
Gibt synchron true
zurück, wenn der übergebene Wert mit dem Schema übereinstimmt.
Verwendet die gleichen Optionen wie validateSync()
und weist die gleichen Einschränkungen bei asynchronen Tests auf.
Schema.cast(value: any, options = {}): InferType<Schema>
Versucht, den übergebenen Wert in einen Wert umzuwandeln, der dem Schema entspricht. Beispiel: '5'
wird bei Verwendung des Typs number()
in 5
umgewandelt. Fehlgeschlagene Umwandlungen geben im Allgemeinen null
zurück, können aber auch Ergebnisse wie NaN
und unerwartete Zeichenfolgen zurückgeben.
Stellen Sie options
bereit, um das Verhalten von validate
genauer zu steuern.
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>
Führt eine Typprüfung anhand des übergebenen value
durch. Bei Übereinstimmung wird true zurückgegeben, der Wert wird nicht umgewandelt. Wenn nullable()
festgelegt ist, wird null
als gültiger Wert des Typs betrachtet. Sie sollten isType
für alle Schematypprüfungen verwenden.
Schema.strict(enabled: boolean = false): Schema
Setzt die Option strict
auf true
. Strenge Schemata verzichten auf Zwang und Transformationsversuche und validieren den Wert „wie er ist“.
Schema.strip(enabled: boolean = true): Schema
Markiert ein Schema, das aus einem Ausgabeobjekt entfernt werden soll. Funktioniert nur als verschachteltes Schema.
let schema = object ( {
useThis : number ( ) ,
notThis : string ( ) . strip ( ) ,
} ) ;
schema . cast ( { notThis : 'foo' , useThis : 4 } ) ; // => { useThis: 4 }
Schemas mit aktiviertem strip
haben den abgeleiteten Typ never
, wodurch sie aus dem Gesamttyp entfernt werden können:
let schema = object ( {
useThis : number ( ) ,
notThis : string ( ) . strip ( ) ,
} ) ;
InferType < typeof schema > ; /*
{
useThis?: number | undefined
}
*/
Schema.withMutation(builder: (current: Schema) => void): void
Zuerst das gesetzlich vorgeschriebene Zitat von Rich Hickey:
Wenn ein Baum im Wald fällt, macht das dann ein Geräusch?
Wenn eine reine Funktion einige lokale Daten verändert, um einen unveränderlichen Rückgabewert zu erzeugen, ist das in Ordnung?
withMutation
ermöglicht es Ihnen, das Schema an Ort und Stelle zu ändern, anstelle des Standardverhaltens, das vor jeder Änderung klont. Im Allgemeinen ist dies nicht erforderlich, da die überwiegende Mehrheit der Schemaänderungen während der Erstdeklaration und nur einmal über die Lebensdauer des Schemas erfolgt, sodass die Leistung kein Problem darstellt. Allerdings treten bestimmte Mutationen zum Zeitpunkt der Umwandlung/Validierung auf (z. B. bedingtes Schema mit when()
) oder beim Instanziieren eines Schemaobjekts.
object ( )
. shape ( { key : string ( ) } )
. withMutation ( ( schema ) => {
return arrayOfObjectTests . forEach ( ( test ) => {
schema . test ( test ) ;
} ) ;
} ) ;
Schema.default(value: any): Schema
Legt einen Standardwert fest, der verwendet wird, wenn der Wert undefined
ist. Standardwerte werden nach der Ausführung von Transformationen, aber vor Validierungen erstellt, um sicherzustellen, dass sichere Standardwerte angegeben werden. Der Standardwert wird bei jeder Verwendung geklont, was zu Leistungseinbußen bei Objekten und Arrays führen kann. Um diesen Mehraufwand zu vermeiden, können Sie auch eine Funktion übergeben, die einen neuen Standardwert zurückgibt. Beachten Sie, dass null
als separater, nicht leerer Wert betrachtet wird.
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
Rufen Sie einen zuvor festgelegten Standardwert ab. getDefault
löst alle Bedingungen auf, die die Standardeinstellung ändern könnten. Übergeben Sie optional options
mit context
(weitere Informationen zum context
finden Sie unter Schema.validate
).
Schema.nullable(message?: string | function): Schema
Gibt an, dass null
ein gültiger Wert für das Schema ist. Ohne nullable()
wird null
als ein anderer Typ behandelt und schlägt die Prüfungen Schema.isType()
fehl.
let schema = number ( ) . nullable ( ) ;
schema . cast ( null ) ; // null
InferType < typeof schema > ; // number | null
Schema.nonNullable(message?: string | function): Schema
Das Gegenteil von nullable
entfernt null
aus gültigen Typwerten für das Schema. Schemas sind standardmäßig nicht nullfähig .
let schema = number ( ) . nonNullable ( ) ;
schema . cast ( null ) ; // TypeError
InferType < typeof schema > ; // number
Schema.defined(): Schema
Erfordert einen Wert für das Schema. Alle Feldwerte außer undefined
erfüllen diese Anforderung.
let schema = string ( ) . defined ( ) ;
schema . cast ( undefined ) ; // TypeError
InferType < typeof schema > ; // string
Schema.optional(): Schema
Das Gegenteil von defined()
erlaubt undefined
Werte für den angegebenen Typ.
let schema = string ( ) . optional ( ) ;
schema . cast ( undefined ) ; // undefined
InferType < typeof schema > ; // string | undefined
Schema.required(message?: string | function): Schema
Markieren Sie das Schema als erforderlich, sodass undefined
oder null
nicht als Wert zulässig ist. required
negiert die Auswirkungen des Aufrufs optional()
und nullable()
Achtung!
string().required
) funktioniert etwas anders und verhindert bei Bedarf zusätzlich leere Zeichenfolgenwerte (''
).
Schema.notRequired(): Schema
Markieren Sie das Schema als nicht erforderlich. Dies ist eine Abkürzung für schema.nullable().optional()
;
Schema.typeError(message: string): Schema
Definieren Sie eine Fehlermeldung für fehlgeschlagene Typprüfungen. Die Interpolation ${value}
und ${type}
kann im message
verwendet werden.
Schema.oneOf(arrayOfValues: Array<any>, message?: string | function): Schema
Alias: equals
Nur Werte aus Wertesätzen zulassen. Hinzugefügte Werte werden aus allen notOneOf
-Werten entfernt, sofern vorhanden. Die ${values}
-Interpolation kann im message
verwendet werden. Wenn eine oder mehrere Referenzen bereitgestellt werden, kann die Interpolation ${resolved}
im Nachrichtenargument verwendet werden, um die aufgelösten Werte abzurufen, die zum Zeitpunkt der Validierung überprüft wurden.
Beachten Sie, dass undefined
diesen Validator nicht fehlschlägt, auch wenn undefined
nicht in arrayOfValues
enthalten ist. Wenn Sie nicht möchten, dass undefined
ein gültiger Wert ist, können Sie Schema.required
verwenden.
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)
Werte aus einer Wertemenge nicht zulassen. Hinzugefügte Werte werden aus oneOf
Werten entfernt, sofern vorhanden. Die ${values}
-Interpolation kann im message
verwendet werden. Wenn eine oder mehrere Referenzen bereitgestellt werden, kann die Interpolation ${resolved}
im Nachrichtenargument verwendet werden, um die aufgelösten Werte abzurufen, die zum Zeitpunkt der Validierung überprüft wurden.
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
Passen Sie das Schema basierend auf den Feldern „Geschwister“ oder „Geschwisterkinder“ an. Sie können ein Objektliteral bereitstellen, bei dem der Schlüssel ein Wert oder eine Matcher-Funktion is
, then
das wahre Schema und/oder otherwise
für die Fehlerbedingung bereitstellen.
is
Bedingungen werden streng verglichen ( ===
). Wenn Sie eine andere Form der Gleichheit verwenden möchten, können Sie eine Funktion wie folgt bereitstellen: is: (value) => value == true
.
Sie können Eigenschaften auch mit dem Präfix $
versehen, um eine Eigenschaft anzugeben, die vom context
abhängt, der von validate()
übergeben oder anstelle des Eingabewerts cast
.
when
die Bedingungen additiv sind.
then
und otherwise
sind angegebene Funktionen (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 } } ) ;
Sie können auch mehr als einen abhängigen Schlüssel angeben. In diesem Fall wird jeder Wert als Argument verteilt.
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 ,
} ) ;
Alternativ können Sie eine Funktion bereitstellen, die ein Schema zurückgibt, das mit einem Array von Werten für jeden bereitgestellten Schlüssel des aktuellen Schemas aufgerufen wird.
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
Fügt der Validierungskette eine Testfunktion hinzu. Tests werden ausgeführt, nachdem ein Objekt umgewandelt wurde. Bei vielen Typen sind einige Tests integriert, Sie können jedoch problemlos benutzerdefinierte Tests erstellen. Um asynchrone benutzerdefinierte Validierungen zu ermöglichen, werden alle (oder keine) Tests asynchron ausgeführt. Dies hat zur Folge, dass die Reihenfolge der Testausführung nicht garantiert werden kann.
Alle Tests müssen einen name
, eine message
und eine Validierungsfunktion bereitstellen, die true
zurückgeben muss, wenn der aktuelle value
gültig ist, andernfalls false
oder einen ValidationError
. Um einen asynchronen Test zu veranlassen, ein Versprechen zurückzugeben, das true
oder false
auflöst, oder einen ValidationError
.
Für das message
können Sie eine Zeichenfolge angeben, die bestimmte Werte interpoliert, wenn sie mit der ${param}
-Syntax angegeben werden. Standardmäßig wird allen Testnachrichten ein path
übergeben, der in verschachtelten Schemata nützlich ist.
Die test
wird mit dem aktuellen value
aufgerufen. Für erweiterte Validierungen können Sie die alternative Signatur verwenden, um weitere Optionen bereitzustellen (siehe unten):
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
Testfunktionen werden mit einem speziellen Kontextwert als zweitem Argument aufgerufen, der einige nützliche Metadaten und Funktionen offenlegt. Für Nicht-Pfeilfunktionen wird der Testkontext auch als Funktion this
festgelegt. Achtung, wenn Sie this
darauf zugreifen, funktioniert die Pfeilfunktion nicht.
testContext.path
: der Zeichenfolgenpfad der aktuellen ValidierungtestContext.schema
: das aufgelöste Schemaobjekt, für das der Test ausgeführt wird.testContext.options
: das options
, mit dem validate() oder isValid() aufgerufen wurdetestContext.parent
: Im Fall eines verschachtelten Schemas ist dies der Wert des übergeordneten ObjektstestContext.originalValue
: der ursprüngliche Wert, der getestet wirdtestContext.createError(Object: { path: String, message: String, params: Object })
: erstellt einen Validierungsfehler und gibt ihn zurück. Nützlich zum dynamischen Festlegen des path
, params
oder, was wahrscheinlicher ist, der message
. Wenn eine der Optionen weggelassen wird, wird der aktuelle Pfad oder die Standardnachricht verwendet. Schema.test(options: object): Schema
Alternative test(..)
-Signatur. options
ist ein Objekt, das einige der folgenden Optionen enthält:
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 ;
}
Bei der Mischung von exklusiven und nicht-exklusiven Tests kommt die folgende Logik zum Einsatz. Wenn einem Schema ein nicht-exklusiver Test mit einem gleichnamigen exklusiven Test hinzugefügt wird, wird der exklusive Test entfernt und weitere Tests mit demselben Namen werden gestapelt.
Wenn einem Schema ein exklusiver Test mit nicht-exklusiven Tests mit demselben Namen hinzugefügt wird, werden die vorherigen Tests entfernt und weitere Tests mit demselben Namen ersetzen einander.
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
Fügt der Transformationskette eine Transformation hinzu. Transformationen sind für den Casting-Prozess von zentraler Bedeutung. Standardtransformationen für jeden Typ erzwingen Werte für den spezifischen Typ (wie durch isType()
überprüft). Transformationen werden vor Validierungen ausgeführt und nur angewendet, wenn das Schema nicht als strict
markiert ist (Standardeinstellung). Einige Typen verfügen über integrierte Transformationen.
Transformationen sind nützlich, um die Art und Weise, wie das Objekt umgewandelt wird, willkürlich zu ändern. Sie sollten jedoch darauf achten, den übergebenen Wert nicht zu verändern. Transformationen werden nacheinander ausgeführt, sodass jeder value
den aktuellen Status der Umwandlung darstellt. Sie können den Parameter originalValue
verwenden, wenn Sie am rohen Anfangswert arbeiten müssen.
let schema = string ( ) . transform ( ( value , originalValue ) => {
return this . isType ( value ) && value !== null ? value . toUpperCase ( ) : value ;
} ) ;
schema . cast ( 'jimmy' ) ; // => 'JIMMY'
Jeder Typ übernimmt die grundlegende Konvertierung von Werten in den richtigen Typ für Sie. Gelegentlich möchten Sie jedoch möglicherweise das Standardverhalten anpassen oder verfeinern. Wenn Sie beispielsweise eine andere Datumsanalysestrategie als die Standardstrategie verwenden möchten, können Sie dies mit einer Transformation tun.
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 ( '' ) ;
} ) ;
} ;
Erstellt ein Schema, das allen Typen oder nur den von Ihnen konfigurierten Typen entspricht. Erbt von Schema
. Gemischte Typen erweitern standardmäßig {}
anstelle von any
oder unknown
. Dies liegt daran, dass {}
in TypeScript alles bedeutet, was nicht null
oder undefined
ist, was yup eindeutig behandelt.
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
Benutzerdefinierte Typen können durch Übergeben einer check
implementiert werden. Dadurch wird auch der TypeScript-Typ für das Schema eingeschränkt.
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
Definieren Sie ein String-Schema. Erbt von Schema
.
let schema = yup . string ( ) ;
await schema . isValid ( 'hello' ) ; // => true
Standardmäßig besteht die cast
von string
darin, toString
für den Wert aufzurufen, sofern dieser vorhanden ist.
Leere Werte werden nicht erzwungen (verwenden Sie ensure()
um leere Werte in leere Zeichenfolgen zu erzwingen).
Fehlgeschlagene Umwandlungen geben den Eingabewert zurück.
string.required(message?: string | function): Schema
Dasselbe wie das erforderliche mixed()
-Schema, mit der Ausnahme , dass leere Zeichenfolgen ebenfalls als „fehlende“ Werte betrachtet werden.
string.length(limit: number | Ref, message?: string | function): Schema
Legen Sie eine erforderliche Länge für den Zeichenfolgenwert fest. Die ${length}
-Interpolation kann im message
verwendet werden
string.min(limit: number | Ref, message?: string | function): Schema
Legen Sie eine Mindestlängenbeschränkung für den Zeichenfolgenwert fest. Die ${min}
-Interpolation kann im message
verwendet werden
string.max(limit: number | Ref, message?: string | function): Schema
Legen Sie eine maximale Längenbeschränkung für den Zeichenfolgenwert fest. Die ${max}
-Interpolation kann im message
verwendet werden
string.matches(regex: Regex, message?: string | function): Schema
Geben Sie einen beliebigen regex
an, mit dem der Wert abgeglichen werden soll.
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
Eine alternative Signatur für string.matches
mit einem Optionsobjekt. Wenn excludeEmptyString
wahr ist, wird der Regex-Test kurzgeschlossen, wenn der Wert ein leerer String ist. So lässt sich leichter vermeiden, dass nichts gefunden wird, ohne dass der Regex komplizierter wird.
let schema = string ( ) . matches ( / (hi|bye) / , { excludeEmptyString : true } ) ;
await schema . isValid ( '' ) ; // => true
string.email(message?: string | function): Schema
Validiert den Wert als E-Mail-Adresse unter Verwendung desselben regulären Ausdrucks, der in der HTML-Spezifikation definiert ist.
ACHTUNG: Die Validierung von E-Mail-Adressen allein mit Code ist nahezu unmöglich. Verschiedene Clients und Server akzeptieren unterschiedliche Dinge und viele weichen von den verschiedenen Spezifikationen ab, die „gültige“ E-Mails definieren. Die EINZIGE echte Möglichkeit, eine E-Mail-Adresse zu validieren, besteht darin, eine Bestätigungs-E-Mail an sie zu senden und zu überprüfen, ob der Benutzer sie erhalten hat. Vor diesem Hintergrund wählt yup einen relativ einfachen regulären Ausdruck, der nicht alle Fälle abdeckt, sich aber an das Verhalten der Browser-Eingabevalidierung anpasst, da HTML-Formulare ein häufiger Anwendungsfall für yup sind.
Wenn Sie spezifischere Anforderungen haben, überschreiben Sie bitte die E-Mail-Methode mit Ihrer eigenen Logik oder Regex:
yup . addMethod ( yup . string , 'email' , function validateEmail ( message ) {
return this . matches ( myEmailRegex , {
message ,
name : 'email' ,
excludeEmptyString : true ,
} ) ;
} ) ;
string.url(message?: string | function): Schema
Validiert den Wert als gültige URL über einen regulären Ausdruck.
string.uuid(message?: string | function): Schema
Validiert den Wert als gültige UUID über einen regulären Ausdruck.
string.datetime(options?: {message?: string | function, allowOffset?: boolean, precision?: number})
Validiert den Wert als ISO-Datum/Uhrzeit-Wert über einen regulären Ausdruck. Standardmäßig wird die UTC-Validierung verwendet. Zeitzonenoffsets sind nicht zulässig (siehe options.allowOffset
).
Im Gegensatz zu .date()
konvertiert datetime
die Zeichenfolge nicht in ein Date
Objekt. datetime
ermöglicht außerdem eine stärkere Anpassung des erforderlichen Formats der datetime-Zeichenfolge als date
.
options.allowOffset
: Ermöglicht einen Zeitzonenversatz. False erfordert die UTC-Zeitzone „Z“. (Standard: false) options.precision
: Erfordert eine bestimmte Genauigkeit in Sekundenbruchteilen für das Datum. (Standard: null – jede (oder keine) Genauigkeit im Subsekundenbereich)
string.datetime(message?: string | function)
Eine alternative Signatur für string.datetime
, die verwendet werden kann, wenn Sie keine anderen Optionen als message
übergeben müssen.
string.ensure(): Schema
Wandelt undefined
Werte und null
in eine leere Zeichenfolge um und legt den default
auf eine leere Zeichenfolge fest.
string.trim(message?: string | function): Schema
Transformiert Zeichenfolgenwerte durch Entfernen führender und nachfolgender Leerzeichen. Wenn strict()
festgelegt ist, wird nur überprüft, ob der Wert gekürzt wurde.
string.lowercase(message?: string | function): Schema
Wandelt den Zeichenfolgenwert in Kleinbuchstaben um. Wenn strict()
festgelegt ist, wird nur überprüft, ob der Wert klein geschrieben ist.
string.uppercase(message?: string | function): Schema
Wandelt den Zeichenfolgenwert in Großbuchstaben um. Wenn strict()
festgelegt ist, wird nur überprüft, ob der Wert in Großbuchstaben geschrieben ist.
Definieren Sie ein Zahlenschema. Erbt von Schema
.
let schema = yup . number ( ) ;
await schema . isValid ( 10 ) ; // => true
Die cast
von number
ist: parseFloat
.
Fehlgeschlagene Umwandlungen geben NaN
zurück.
number.min(limit: number | Ref, message?: string | function): Schema
Legen Sie den zulässigen Mindestwert fest. Die ${min}
-Interpolation kann im message
verwendet werden.
number.max(limit: number | Ref, message?: string | function): Schema
Legen Sie den maximal zulässigen Wert fest. Die ${max}
-Interpolation kann im message
verwendet werden.
number.lessThan(max: number | Ref, message?: string | function): Schema
Der Wert muss kleiner als max
sein. Die ${less}
-Interpolation kann im message
verwendet werden.
number.moreThan(min: number | Ref, message?: string | function): Schema
Der Wert muss unbedingt größer als min
sein. Die ${more}
-Interpolation kann im message
verwendet werden.
number.positive(message?: string | function): Schema
Der Wert muss eine positive Zahl sein.
number.negative(message?: string | function): Schema
Der Wert muss eine negative Zahl sein.
number.integer(message?: string | function): Schema
Überprüft, ob eine Zahl eine ganze Zahl ist.
number.truncate(): Schema
Transformation, die den Wert in eine Ganzzahl umwandelt, indem die Ziffern rechts vom Dezimalpunkt entfernt werden.
number.round(type: 'floor' | 'ceil' | 'trunc' | 'round' = 'round'): Schema
Passt den Wert über die angegebene Methode von Math
an (Standard ist „runden“).
Definieren Sie ein boolesches Schema. Erbt von Schema
.
let schema = yup . boolean ( ) ;
await schema . isValid ( true ) ; // => true
Definieren Sie ein Datumsschema. Standardmäßig werden ISO-Datumszeichenfolgen korrekt analysiert. Robustere Analyseoptionen finden Sie in den erweiterten Schematypen am Ende der Readme-Datei. Erbt von Schema
.
let schema = yup . date ( ) ;
await schema . isValid ( new Date ( ) ) ; // => true
Die standardmäßige cast
von date
besteht darin, den Wert an den Date
Konstruktor zu übergeben. Andernfalls wird versucht, das Datum als ISO-Datumszeichenfolge zu analysieren.
Wenn Sie möchten, dass ISO-Strings nicht in ein
Date
-Objekt umgewandelt werden, verwenden Sie stattdessen.datetime()
.
Fehlgeschlagene Umwandlungen geben ein ungültiges Datum zurück.
date.min(limit: Date | string | Ref, message?: string | function): Schema
Legen Sie das zulässige Mindestdatum fest. Wenn eine Zeichenfolge bereitgestellt wird, wird zunächst versucht, eine Umwandlung in ein Datum durchzuführen und das Ergebnis als Grenzwert zu verwenden.
date.max(limit: Date | string | Ref, message?: string | function): Schema
Legen Sie das maximal zulässige Datum fest. Wenn eine Zeichenfolge bereitgestellt wird, wird zunächst versucht, in ein Datum umzuwandeln und das Ergebnis als Grenzwert zu verwenden.
Definieren Sie ein Array-Schema. Arrays können typisiert sein oder nicht. Bei der Angabe des Elementtyps gelten cast
und isValid
auch für die Elemente. An isValid
übergebene Optionen werden auch an untergeordnete Schemas übergeben.
Erbt von 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]
Sie können der Einfachheit halber auch ein Subtypschema an den Array-Konstruktor übergeben.
array ( ) . of ( yup . number ( ) ) ;
// or
array ( yup . number ( ) ) ;
Arrays haben kein standardmäßiges Umwandlungsverhalten.
array.of(type: Schema): this
Geben Sie das Schema der Array-Elemente an. of()
ist optional und wenn es weggelassen wird, validiert das Array-Schema seinen Inhalt nicht.
array.json(): this
Versuchen Sie, Eingabezeichenfolgenwerte mit JSON.parse
als JSON zu analysieren.
array.length(length: number | Ref, message?: string | function): this
Legen Sie eine bestimmte Längenanforderung für das Array fest. Die ${length}
-Interpolation kann im message
verwendet werden.
array.min(limit: number | Ref, message?: string | function): this
Legen Sie eine Mindestlängenbeschränkung für das Array fest. Die ${min}
-Interpolation kann im message
verwendet werden.
array.max(limit: number | Ref, message?: string | function): this
Legen Sie eine maximale Längenbeschränkung für das Array fest. Die ${max}
-Interpolation kann im message
verwendet werden.
array.ensure(): this
Stellt sicher, dass der Wert ein Array ist, indem der Standardwert auf []
gesetzt wird und null
und undefined
Werte ebenfalls in ein leeres Array umgewandelt werden. Jeder nicht leere Nicht-Array-Wert wird in ein Array eingeschlossen.
array ( ) . ensure ( ) . cast ( null ) ; // => []
array ( ) . ensure ( ) . cast ( 1 ) ; // => [1]
array ( ) . ensure ( ) . cast ( [ 1 ] ) ; // => [1]
array.compact(rejector: (value) => boolean): Schema
Entfernt falsche Werte aus dem Array. Durch die Bereitstellung einer Ablehnungsfunktion können Sie die Ablehnungskriterien selbst festlegen.
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]
Tupel sind Arrays fester Länge, bei denen jedes Element einen eigenen Typ hat.
Erbt von 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
Tupel haben kein Standardumwandlungsverhalten.
Definieren Sie ein Objektschema. An isValid
übergebene Optionen werden auch an untergeordnete Schemas übergeben. Erbt von Schema
.
yup . object ( {
name : string ( ) . required ( ) ,
age : number ( ) . required ( ) . positive ( ) . integer ( ) ,
email : string ( ) . email ( ) ,
website : string ( ) . url ( ) ,
} ) ;
Auf das Objektschema werden keine Standardtransformationen angewendet.
Objektschemata verfügen über einen bereits festgelegten Standardwert, der die Objektform „aufbaut“ und alle Standardwerte für Felder festlegt:
let schema = object ( {
name : string ( ) . default ( '' ) ,
} ) ;
schema . default ( ) ; // -> { name: '' }
Dies mag etwas überraschend sein, ist aber in der Regel hilfreich, da es großen, verschachtelten Schemata ermöglicht, Standardwerte zu erstellen, die die gesamte Form und nicht nur das Stammobjekt ausfüllen. Es gibt ein Problem! obwohl. Bei verschachtelten Objektschemata, die optional sind, aber nicht optionale Felder enthalten, kann es auf unerwartete Weise zu Fehlern kommen:
let schema = object ( {
id : string ( ) . required ( ) ,
names : object ( {
first : string ( ) . required ( ) ,
} ) ,
} ) ;
schema . isValid ( { id : 1 } ) ; // false! names.first is required
Dies liegt daran, dass yup das Eingabeobjekt umwandelt, bevor die Validierung ausgeführt wird, was zu Folgendem führt:
{ id: '1', names: { first: undefined }}
Während der Validierungsphase ist names
vorhanden und wird validiert, wobei names.first
fehlt. Wenn Sie dieses Verhalten vermeiden möchten, führen Sie einen der folgenden Schritte aus:
names.default(undefined)
names.nullable().default(null)
object.shape(fields: object, noSortEdges?: Array<[string, string]>): Schema
Definieren Sie die Schlüssel des Objekts und die Schemata für diese Schlüssel.
Beachten Sie, dass Sie shape
-Methode verketten können, die sich wie Object.assign
verhält.
object ( {
a : string ( ) ,
b : number ( ) ,
} ) . shape ( {
b : string ( ) ,
c : number ( ) ,
} ) ;
wäre genau das gleiche wie:
object ( {
a : string ( ) ,
b : string ( ) ,
c : number ( ) ,
} ) ;
object.json(): this
Versuchen Sie, Eingabezeichenfolgenwerte mit JSON.parse
als JSON zu analysieren.
object.concat(schemaB: ObjectSchema): ObjectSchema
Erstellt ein Objektschema, indem alle Einstellungen und Felder von schemaB
auf die Basis angewendet werden, wodurch ein neues Schema erstellt wird. Die Objektform wird flach zusammengeführt, wobei gemeinsame Felder aus schemaB
Vorrang vor den Basisfeldern haben.
object.pick(keys: string[]): Schema
Erstellen Sie ein neues Schema aus einer Teilmenge der Felder des Originals.
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
Erstellen Sie ein neues Schema mit weggelassenen Feldern.
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
Wandelt den angegebenen Schlüssel in einen neuen Schlüssel um. Wenn alias
true
ist, wird der alte Schlüssel beibehalten.
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
Überprüfen Sie, ob der Objektwert nur in shape
angegebene Schlüssel enthält. Übergeben Sie false
als erstes Argument, um die Prüfung zu deaktivieren. Durch die Beschränkung der Schlüssel auf bekannte wird auch die Option stripUnknown
aktiviert, wenn der strikte Modus nicht aktiviert ist.
object.camelCase(): Schema
Wandelt alle Objektschlüssel in camelCase um
object.constantCase(): Schema
Wandelt alle Objektschlüssel in CONSTANT_CASE um.