How to type return of hook based on string passed as argument?

I wanna have different types based on string passed as the argument of a custom hook, but i don't know how to infer types of zod schema dynamically based on a received string. I reckon typescript helpers function might help but i don't know any.
const validations = {
"GET_FRUITS": {
schema: z.object({ fruit: z.string() }),
},
"GET_AMMOUNT": {
schema: z.object({ ammount: z.number() }),
}
}

function useHook = //

const Component = () => {
const { data } = useHook("GET_FRUITS", unparsedData)
// data.fruit === string

const { data } = useHook("GET_AMMOUNT", unparsedData)
// data.ammount === number

return null
}
const validations = {
"GET_FRUITS": {
schema: z.object({ fruit: z.string() }),
},
"GET_AMMOUNT": {
schema: z.object({ ammount: z.number() }),
}
}

function useHook = //

const Component = () => {
const { data } = useHook("GET_FRUITS", unparsedData)
// data.fruit === string

const { data } = useHook("GET_AMMOUNT", unparsedData)
// data.ammount === number

return null
}
3 Replies
Aland
Aland•12mo ago
From chatgpt, not tested!
import { z } from "zod";

const validations = {
"GET_FRUITS": {
schema: z.object({ fruit: z.string() }),
},
"GET_AMOUNT": {
schema: z.object({ amount: z.number() }),
}
};

type Validations = typeof validations;
type ValidationKeys = keyof Validations;

type ExtractData<T extends ValidationKeys> = Validations[T] extends { schema: z.Schema<infer U> } ? U : never;

function useHook<T extends ValidationKeys>(validationKey: T, unparsedData: any) {
const { schema } = validations[validationKey];
const parsedData = schema.parse(unparsedData) as ExtractData<T>;
// Return parsedData or use it in your custom hook implementation
}

const Component = () => {
const { data: fruitsData } = useHook("GET_FRUITS", unparsedData);
// fruitsData is now of type { fruit: string }

const { data: amountData } = useHook("GET_AMOUNT", unparsedData);
// amountData is now of type { amount: number }

return null;
}
import { z } from "zod";

const validations = {
"GET_FRUITS": {
schema: z.object({ fruit: z.string() }),
},
"GET_AMOUNT": {
schema: z.object({ amount: z.number() }),
}
};

type Validations = typeof validations;
type ValidationKeys = keyof Validations;

type ExtractData<T extends ValidationKeys> = Validations[T] extends { schema: z.Schema<infer U> } ? U : never;

function useHook<T extends ValidationKeys>(validationKey: T, unparsedData: any) {
const { schema } = validations[validationKey];
const parsedData = schema.parse(unparsedData) as ExtractData<T>;
// Return parsedData or use it in your custom hook implementation
}

const Component = () => {
const { data: fruitsData } = useHook("GET_FRUITS", unparsedData);
// fruitsData is now of type { fruit: string }

const { data: amountData } = useHook("GET_AMOUNT", unparsedData);
// amountData is now of type { amount: number }

return null;
}
vitor markis 🎈
vitor markis 🎈•12mo ago
It worked man, thx, did you use Chat GPT 4?
Aland
Aland•12mo ago
Nope just 3.5