I have this:
const E = [
'3dostr',
'3g2',
...
'xwd_pipe',
'xwma',
'yop',
'yuv4mpegpipe',
]
type FfmpegFormatContentKey = (typeof E)[number]
export const FfmpegFormatContentKeyModel: z.ZodType<FfmpegFormatContentKey> =
z.enum(E)
At the very bottom:
export const FfmpegFormatContentKeyModel: z.ZodType<FfmpegFormatContentKey> =
z.enum(E)
That doesn't work, giving this error with no "quick fixes" available:
No overload matches this call.
Overload 1 of 2, '(values: readonly [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'string[]' is not assignable to parameter of type 'readonly [string, ...string[]]'.
Source provides no match for required element at position 0 in target.
Overload 2 of 2, '(values: [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'string[]' is not assignable to parameter of type '[string, ...string[]]'.
Source provides no match for required element at position 0 in target.ts(2769)
const E: string[]
It looks like it is expecting the explicit array directly in the input, like this:
export const FfmpegFormatContentKeyModel: z.ZodType<FfmpegFormatContentKey> =
z.enum(['3dostr', '3g2', '3gp', '4xm', 'a64'])
That works, now. It works just fine putting all those values explicitly/directly in the input for z.enum
.
Goal: The goal is to not include these large arrays twice in the final output JS.
export const MY_ARRAY = [...]
.export const MyArrayModel = z.enum([...])
.How can I do that?
Perhaps there is something like:
export const MY_ARRAY = MyArrayModel.getEnumArray()
Or something like that?
Or perhaps there is some way to format the input to z.enum
so it accepts a variable name like z.enum(X)
?
I need both forms of the values, array and enum, in the final JS output. The array will be used for things like constructing React <select>
options, and the enum will be used for validating method arguments, etc.. So both are needed, but just not sure how to get both without explicitly writing both to the output JS build.
I tried this as well:
export const FfmpegDecoderAudioModel: z.ZodType<FfmpegDecoderAudio> =
z.enum(X as readonly [string, ...string])
But get a similar error:
Conversion of type 'string[]' to type 'readonly [string, ...any[]]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Source provides no match for required element at position 0 in target.ts(2352)
This seems to work, but is there a better way?
export const FfmpegDecoderAudioModel: z.ZodType<FfmpegDecoderAudio> =
z.enum(X as unknown as readonly [string, ...Array<string>])
The zod.enum
requires values: readonly [string, ...string[]]
, which means we have to pass it readonly array with at least one value.
Your const E
is not readonly array. Typescript needs some more.
You need to state the const E
to be deep readonly
. you have not protected that no one can programmatically add values to the array.
The way to do is to use the as const
trailing operator.
const E = [ ... ] as const;
Working example here
More info on the as const
trailing annotation here