Вопрос или проблема
Ошибка типа при преобразовании входных данных с помощью Zod
Я пытаюсь написать функцию декодирования (decode
), которая принимает схему Zod и входные данные типа unknown
. Она должна уметь как валидировать входные данные, так и преобразовывать их, если входные и выходные типы кода Zod различаются.
Когда я пытаюсь сделать это следующим образом:
import { ZodSchema, z } from 'zod'
const DateFromString = z.string().transform(input => new Date(input))
const Event = z.object({ timestamp: DateFromString })
const decode = <T>(schema: ZodSchema<T>, data: unknown): T => schema.parse(data)
const { timestamp } = decode(Event, { timestamp: '2024-01-01' })
Я получаю следующую ошибку типа:
Типы ‘_input.timestamp’ несовместимы между этими типами. Тип ‘string’ не может быть присвоен типу ‘Date’.(2345)
Есть ли способ исправить эту ошибку типа и убедиться, что переменная timestamp
на последней строке имеет тип Date
?
Ответ или решение
Для решения вашей проблемы с преобразованием типов при использовании библиотеки Zod, вы можете воспользоваться "сжатым" типом возвращаемого значения, чтобы избежать ошибки типов, возникающей из-за разницы между входными и выходными типами.
Ваша текущая реализация функции decode
вызывает ошибку типов, поскольку в типе, который вы передаёте в parse
, Zod ожидает, что все свойства соответствуют входным типам схемы, но в вашем случае timestamp
должен быть преобразован в Date
.
Для исправления этой ошибки, необходимо явно указать, что схема возвращает тип после трансформации. Для этого вы можете изменить определение функции decode
, указав, что возвращаемый тип соответствует результату трансформации, как показано ниже:
import { ZodSchema, z } from 'zod'
const DateFromString = z.string().transform(input => new Date(input))
const Event = z.object({ timestamp: DateFromString })
// Изменяем функцию decode, чтобы возвращаемый тип соответствовал результату трансформации
const decode = <T>(schema: ZodSchema<T>): (data: unknown) => T => {
return (data: unknown) => schema.parse(data)
}
// Теперь timestamp будет иметь правильный тип Date
const { timestamp } = decode(Event)({ timestamp: '2024-01-01' })
Пояснение:
-
Тип возвращаемого значения: Изменение декларации функции
decode
позволяет явно указать, что она будет обрабатывать входное значениеunknown
и возвращать результат, который будет соответствовать установленной Zod-схеме. Таким образом, возвращаемый типT
будет включать уже преобразованный тип. - Использование
parse
: Методparse
библиотеки Zod не только проверяет входные данные на соответствие схеме, но и выполняет трансформацию, так что после его вызоваtimestamp
будет иметь типDate
, как вы и ожидаете.
После внесения этих исправлений, ваша ситуация с типами должна быть полностью устранена, и переменная timestamp
будет являться экземпляром Date
.