-
Notifications
You must be signed in to change notification settings - Fork 24
/
coercions.ts
58 lines (46 loc) · 1.35 KB
/
coercions.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { ZodTypeAny } from 'zod'
import { shapeInfo } from './shapeInfo'
function makeCoercion<T>(
coercion: (value: FormDataEntryValue) => T,
emptyValue: unknown,
) {
return ({
value,
optional,
nullable,
}: {
value: FormDataEntryValue | null
optional: boolean
nullable: boolean
}) => {
if (value) return coercion(value)
if (nullable) return null
if (optional) return undefined
return emptyValue
}
}
const coerceString = makeCoercion(String, '')
const coerceNumber = makeCoercion(Number, null)
const coerceBoolean = makeCoercion(Boolean, false)
const coerceDate = makeCoercion((value) => {
if (typeof value !== 'string') return null
const [year, month, day] = value.split('-').map(Number)
return new Date(year, month - 1, day)
}, null)
function coerceValue(value: FormDataEntryValue | null, shape?: ZodTypeAny) {
const { typeName, optional, nullable } = shapeInfo(shape)
if (typeName === 'ZodBoolean') {
return coerceBoolean({ value, optional, nullable })
}
if (typeName === 'ZodNumber') {
return coerceNumber({ value, optional, nullable })
}
if (typeName === 'ZodDate') {
return coerceDate({ value, optional, nullable })
}
if (typeName === 'ZodString' || typeName === 'ZodEnum') {
return coerceString({ value, optional, nullable })
}
return value
}
export { coerceValue }