Почему Zod делает все поля моей схемы необязательными?
Я использую Zod в своем проекте API Express, TypeScript и Mongoose, и при попытке проверить мой пользовательский ввод по пользовательской схеме он возвращает конфликты типов:
Argument of type '{ firstName?: string; lastName?: string; password?: string; passwordConfirmation?: string; email?: string; }' is not assignable to parameter of type 'UserInput'.
Property 'email' is optional in type '{ firstName?: string; lastName?: string; password?: string; passwordConfirmation?: string; email?: string; }' but required in type 'UserInput'
Вот определение схемы:
export const createUserSchema = object({
body: object({
firstName: string({
required_error: 'First name is required',
}),
lastName: string({
required_error: 'Last name is required',
}).nonempty(),
password: string({
required_error: 'Password is required',
})
.nonempty()
.min(6, 'Password too short - should be 6 chars minimum'),
passwordConfirmation: string({
required_error: 'Confirm password is required',
}),
email: string({
required_error: 'Email is required',
})
.email('Not a valid email')
.nonempty(),
}).refine((data) => data.password === data.passwordConfirmation, {
message: 'Passwords do not match',
path: ['passwordConfirmation'],
}),
});
export type CreateUserInput = Omit<TypeOf<typeof createUserSchema>, 'body.passwordConfirmation'>;
export interface UserInput {
email: string;
firstName: string;
lastName: string;
password: string;
}
Как сделать все эти поля схемы Zod необязательными, поскольку по умолчанию они становятся необязательными?
5 ответов
Это может быть вызвано неиспользованием
strict: true
в параметрах компилятора TypeScript, как указано в разделе установки в файле README .
Следующий базовый файл tsconfig.json исправит это:
{
"compilerOptions": {
"strict": true
}
}
Как отметил @pr0gramist в комментариях, принятым ответом должно быть добавление этого параметра в вашtsconfig.json
:
{
"compilerOptions": {
"strictNullChecks": true
}
}
В зависимости от конфигурации zod по умолчанию вам также может потребоваться добавить это в свои схемы:
requiredField: z.string().nonempty()
Этот метод менее интрузивен, чем"strict": true
, что добавляет дополнительные ограничения машинописного текста в вашу базу кода.
Я предлагаю создать базовую версию, а затем расширить ее с помощью «подтверждения пароля» и относительного уточнения. Также важно «выводить» из zod в машинописный текст, чтобы сделать доступным линтинг машинописного текста.
import { object, string, z } from 'zod';
export const userSchema = object({
firstName: string({
required_error: 'First name is required',
}),
lastName: string({
required_error: 'Last name is required',
}).nonempty(),
password: string({
required_error: 'Password is required',
})
.nonempty()
.min(6, 'Password too short - should be 6 chars minimum'),
email: string({
required_error: 'Email is required',
})
.email('Not a valid email')
.nonempty(),
});
type userSchema = z.infer<typeof userSchema>;
export const createUserSchema = object({
body: userSchema
.extend({
passwordConfirmation: string({
required_error: 'Confirm password is required',
}),
})
.refine((data) => data.password === data.passwordConfirmation, {
message: 'Passwords do not match',
path: ['passwordConfirmation'],
}),
});
type createUserSchema = z.infer<typeof createUserSchema>;
const us: userSchema = {
email: '',
firstName: '',
lastName: '',
password: '',
};
const cui: createUserSchema = {
body: {
email: '',
firstName: '',
lastName: '',
password: '',
passwordConfirmation: '',
},
};
Вы все еще можете использовать универсальный тип
Required
чтобы пометить объект как требуется:
export type X = Required<CreateUserInput>
Вы все еще можете сделать это с подобъектами вашей схемы, если у вас есть, например, параметры, тело и запрос:
export type X = Required<CreateUserInput['body']>