Closed emanuel-lundman closed 4 months ago
Sorry for the inconvenience with this. The short answer is that this has been solved in 3.23.2 by setting the default Output
and Input
back to any
from unknown
(as in 3.23.0). This behavior is more intuitive in more cases.
Were that not the case, the real solution here would be to extract both HelloOutput
and HelloInput
like so (if I'm understanding correctly). That is:
type Branded<T, Brand> = T & { __brand: Brand };
type BrandedString = Branded<string, "BrandedString">;
const aBrandedString = z.string() as unknown as z.ZodSchema<BrandedString>;
const helloSchema = z.object({
name: aBrandedString,
});
type HelloOutput = z.output<typeof helloSchema>;
type HelloInput = z.input<typeof helloSchema>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const func = (hello: z.ZodObject<any, any, any, HelloOutput, HelloInput>) => {
// ...
};
const funcResult = func(helloSchema); // this type works now
I can see you closed the issue. Just jotting down for history.
I had tested 3.23, but that didn't do it. However, the new 3.24 did. (I can see that it reverted back to Input = Output).
The real solution provided in code I don't think would help us because in our real code the func is a generic (I mentioned it briefly but not in the simplified example code). All we know at the time of writing is the generic type, we don't know the schema. So if I'm not forgetting anything obvious (bit tired after a busy week) in our case, the solution wouldn't be the desired route we would like to take, would mean adding a lot of code.
Anyway, thank you for your response! And since the reversion in 3.24 it's all working again.
We have a code base, where we've used branded strings for a long time. (before ZodBranded was added). And to make that work, I believe the recommended way at the time was for them to be cast as
ZodSchema<BrandedStringType>
We also have a function requiring a ZodObject with a defined Input and Output. (we need the .shape property) After upgrading to 3.23, what's the best workaround for this, here's an example where the type checking is getting angry:
Exemple:
The call to func doesn't like the helloSchema since 3.23 because it now thinks name of hello could be
{ name?: unknown }
We could get around this by doing something like (to mimic zodtypes/zodschema old behavior (Input = Output):
or maybe for convenience:
So my question is, what is the recommended way of getting around and solving these new type issues when upgrading to 3.23? (I should perhaps add that the real
func
is generic, and theHello
type is passed as a generic type). Is it reverting back to setting Input = Output manually like it was before the best way, or is there a better way to solve this for the future? Maybe there is a better way to accept a type safe ZodObject as a parameter? We could of course switch to AnyZodObject but then we would loose the type safety of the func hello parameter in the example. 🤔