Trouble with return type of generic funcion #2858
-
I read the description how to type functions which accept a schema but I still fail to type my case both correctly and easily. My context: I want to write a function which accepts a schema and returns a new function which takes a string, parses that string as JSON and then with the given schema. If there is an error, that error is post-processed. Here is my resulting code (also available in a playground): import { z } from "zod";
const transformError = (error: Error) => error.message.toUpperCase();
const someSchema = z.object({
username: z.string(),
});
const parseWithPrettifiedErrorMessage =
<T extends z.ZodTypeAny>(schema: T) =>
(content: string) => {
const result = schema.safeParse(JSON.parse(content));
if (result.success) {
return result;
}
return {
...result,
error: transformError(result.error),
};
};
export const parseSomeSchema = parseWithPrettifiedErrorMessage(someSchema);
// ^? const parseSomeSchema: (content: string) => z.SafeParseSuccess<any> | { error: string; success: false; }
const result = parseSomeSchema('{"wrong": "content"}');
if (result.success) {
const parsed = result.data;
// ^? const parsed: any
} As you can see on the lines for I tried to also use import { z } from "zod";
const transformError = (error: Error) => error.message.toUpperCase();
const someSchema = z.object({
username: z.string(),
});
type SomeSchema = z.infer<typeof someSchema>;
const parseWithPrettifiedErrorMessage =
<Out, T extends z.ZodType<Out> = z.ZodTypeAny>(schema: T) =>
(content: string) => {
const result = schema.safeParse(JSON.parse(content));
if (result.success) {
return result;
}
return {
...result,
error: transformError(result.error),
};
};
export const parseSomeSchema =
parseWithPrettifiedErrorMessage<SomeSchema>(someSchema);
// ^? const parseWithPrettifiedErrorMessage: <{ username: string; }, z.ZodTypeAny>(schema: z.ZodTypeAny) => (content: string)...
const result = parseSomeSchema('{"wrong": "content"}');
if (result.success) {
const parsed = result.data;
// ^? const parsed: { username: string; }
} As you can see, now But: Is it also possible to let TypeScript infer the correct return type or do I always need to explicitly specify the result type? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
Beta Was this translation helpful? Give feedback.
-
Since asking my question, the documentation has been supplemented by the section Inferring the inferred type, which describes a solution. With it your async function myFetch<T extends z.ZodTypeAny>(url: string, schema: T) {
const resp = await fetch(url);
const json = await resp.json();
return schema.parse(json) as z.infer<T>;
} My original problematic code can be enhanced by changing the Thanks for your input and reminding me of this question. |
Beta Was this translation helpful? Give feedback.
Since asking my question, the documentation has been supplemented by the section Inferring the inferred type, which describes a solution.
With it your
myFetch
can also be shortened to this:My original problematic code can be enhanced by changing the
return result
toreturn result as z.SafeParseSuccess<z.infer<T>>
Thanks for your input and reminding me of this question.