TypeSafe external API ?
I am currently communicating with an external API and after falling in love with TRPC, I would like to make this communication with the external API as TypeSafe as possible as well.
I am however kinda failing in the basics of figuring out how to return different types, depending on the inputs of my function call.
Example, i can call the same endpoint on my external API with the parameter "withItems", which kinda ends up mimicking the Prisma version of "include" - but unlike the great work Prisma has done - I am unsure how to detect if the programmer (in this case - mostly me), has passed this parameter to my API call function and return a different typesafe-type. I therefore always end up returning a mixed result (one type - or the other).
My models are these (simplified):
My first attempts where to make a function call where I did something similar to this:
However my initial approach resulted in my having to typecast the result from getOrder - since I never succeded in making a "strong" connection between the parameters of the call, and the result.
In comes Zod - which i believe would be my saviour here - but I fail to get Zod working. I simply cannot grasp my head around how I would implement Zod in this kind of structure and get type-safe return.
Hope you can help (and I have formulated my question clear enough)
21 Replies
I'm not that good with TS either but setting up zod is easy.
First you make a new file and export the schema and the type
Then in your API route you can parse the request body like this
You can also use the type
TestMutate
to make the mutation from the client.GitHub
GitHub - mattpocock/zod-fetch: Simple function for building a type-...
Simple function for building a type-safe fetcher with Zod - GitHub - mattpocock/zod-fetch: Simple function for building a type-safe fetcher with Zod
validating with Zod i can do - but how would this work with "type-return depends on the parameter in the function call" ?
Thanks for the resource-paste - I can see the appeal, but I am not entirely sure how this relates to my problem.
I would like to build a function, where the parameter in the function call, has a direct influence on the type(safe) return of the function.
For example, the default fetcher doesnt seem to take into account varying returns from the API - depending on the data pasted into the API itself.
I could surely do this with
items?:Item[]
in the object defintion of Zod, but what wouldn't exactly make it type safe in the level I want - I am looking for that "prisma feel", where my type is 100% what the API returns, without having to test if an object is in the return or not, when i use the data.You can't, it either conforms to your type or fails. You can never be 100%
Yes but the example you paste above is response-validation - I need response validation and typesafe return depending on the parameters sent to GET.
Why not have 2 functions for each call? i think that may be way easier than trying to figure out how to do it with TS, it gets complicated when you want to do stuff like that.
I agree. It would be an easier way out - and its my "gotto failover". However, I feel this is a great place to learn more typescript / Zod, without taking the "easy way out" so to speak 🙂
Well good luck, the last time i tried to go deep on TS i just wasted ~2 weeks, everything was going over my head.
And even chatgpt didn't help, either it coldn't figure it out or i may be a bad Proompter.
Rust was easier to learn than low level TS.
Why would this not do it though
I don't get it
This looks great, you just need to make
Items
optionalno?
Well if there isn't items it will throw an error?
Why would it
Because it expects items to be defined
No
It should only reach that if withItems has been set to true, at which we assume he has called the api assuming items will be there
You need to do
No
Well idk
I am sorry, I am unable to say why this would not do it, as I am not as well versed in TS as you seem to be 🙂 Its a in interested approach with more defined function-names refering to the same function - I was not aware / had forgotten this was possible in TS.
I do believe this could or would give the desired result - at least it looks like a good match, if i interpret the code correctly.
However I could be a bit worried that the complexity of this kind of solution would grow exponentionally with more optional variables being introduced, like
withSeller
, withBuyer
, withStatistics
etc. and as such the suggested solution might just cover the actual example i put forth above.
The approach you have highlighted here, i believe I would be able to use right out of the box as is however - for this one specific case - but I would need a more generic approach, for multiple options - would you agree ?
If anyone else wants to know the answer to this, I managed to build the below code:But you are not validating it