'Fastest-Validator. Create schema with dependency on value
I have two user types - teacher and student.
Teacher schema is:
{
username : string;
firstName : string;
lastName : string;
type : 1; // 1 = teacher
schoolId : objectId;
email : string;
}
Student schema is:
{
username : string;
firstName : string;
lastName : string;
type : 2; // 2 = student
classCode : number;
}
For validation I use fastest-validator. I want to build one schema for it. But if you see, we have some different fields in different types of users (teacher has email and schoolId; student has classCode).
My wish is to build some schema like following pseudocode:
{
username : string,
lastName : string,
firstName: string,
or: [
{ type : 1, ... },
{ type : 2, ... }
]
}
Solution 1:[1]
Please use Json-Schema as it follows standards, it is fast and it has no dependencies.
You can see bellow ObjectTypeDef which helps to produce a correct schema.
The functions isTeacher, isStudent and isTeacherOrStudent will type your object as parameter if function returns true.
The property anyOfis the best answer for you: a schema should be all good, else is false. The conditions should wrap every allowed schemas.
import type { JSONSchema7, JSONSchema7Definition } from 'json-schema';
import { validate } from 'json-schema';
type AnyObject<K extends string | number | symbol = string | number | symbol, T = any> = Record<K, T>;
type ObjectTypeDef<T extends AnyObject> = JSONSchema7 & {
properties: Record<keyof T, JSONSchema7Definition>;
required: (keyof T)[];
};
type Teacher = {
username: string;
firstName: string;
lastName: string;
type: 1;
schoolId: string;
email: string;
};
type Student = {
username: string;
firstName: string;
lastName: string;
type: 2;
classCode: number;
};
const schemaTeacher: ObjectTypeDef<Teacher> = {
properties: {
username: { type: 'string' },
firstName: { type: 'string' },
lastName: { type: 'string' },
type: { const: 1 },
schoolId: { type: 'string' },
email: { type: 'string' },
},
required: ['username', 'firstName', 'lastName', 'type', 'schoolId', 'email'],
additionalProperties: false,
};
const schemaStudent: ObjectTypeDef<Student> = {
properties: {
username: { type: 'string' },
firstName: { type: 'string' },
lastName: { type: 'string' },
type: { const: 2 },
classCode: { type: 'number' },
},
required: ['username', 'firstName', 'lastName', 'type', 'classCode'],
additionalProperties: false,
};
export const isTeacher = (obj: AnyObject): obj is Teacher => validate(obj, schemaTeacher).valid;
export const isStudent = (obj: AnyObject): obj is Student => validate(obj, schemaStudent).valid;
const schemaTeacherOrStudent: JSONSchema7 = {
anyOf: [schemaStudent, schemaTeacher],
};
export const isTeacherOrStudent = (obj: AnyObject): obj is Teacher | Student =>
validate(obj, schemaTeacherOrStudent).valid;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | karkael |
