Iterate over schema
Hello, I'm trying to create dynamic forms that would use ArkType to dynamically generate correct input type, but somehow I cannot find any good way to iterate over the schema. I've tried few things, and the only one that works is accessing
schema.json.required
which is not even part of TS type of JSON (it just exists at runtime). Is there any easier way?
Basically what I'm looking for is for a way to turn some schema
Into some representation that I can use to render components dynamically like
Am I missing something? I've tried to look for solutions on the web, discord and LLMs but didn't find anything useful 😆10 Replies
Actually maybe getting separate validators for each iterated field could be useful so each input would have it's own error message. Not sure if that's possible in ArkType though.
Hey! Totally not your fault for not being able to find anything.
Iterating over keys like this is not yet a well documented part of the API, though I'm working on adding some content on it soon!
What you're looking for is the
.props
property that will exist on an object literal and include the key as a string and value as a Type instance.
You wouldn't necessarily be able to get something like the original definition (string.email
) out, but Type
s give you lots of tools to introspect and make the comparisons you need.
In this case I'm using .expression
which creates a string representation of the TypeThat's what I was looking for. I probably would have found it, but for some reason
.props
is not present on generic Type<T>
only on specific schema. Thank you for pointing me in the right direction.It is only present on Types that extend
object
There are quite a few props/methods like this that are specific to object like .props
or .partial
or methods that only exist on e.g. strings like atLeastLength
or .matching
My signature looks like
So it should be there?
There are some quirks with how TS evaluates this sort of thing in the context of a generic body you might run into. If the behavior is not correct, it is probably a TS bug as the logic in ArkType is essentially "if T extends object the method should be there."
That said usually since it's just a single internal implementation where you have to deal with these quirks, its not so bad to cast once and have it be safe externally.
A couple side notes though that could affect this:
-
{}
technically does not imply object
since it includes primitives other than null
and undefined
as well
- You may have better luck with something like T extends object
or even T extends type.Any<object>
which you can experiment with if you want to try and find a way to avoid casting in the implementationSure, I can work around it, not a big deal (maybe it indeed is TS bug).
both
extends object
and type.Any<object>
don't change anything hereYeah just messed around with it a bit it looks pretty stubborn. There may be a combination of stuff you can use to avoid casting but when you're writing generic functions like this you end up just having to cast often anyways due to limitations of TypeScript (take it from someone who has written a lot)
I see it as a trade off as some lack of safety in a single implementation vs. more precise types for every invocation of that function
Yea, all good. Thanks again for pointing me in the right direction :-)
Oh I actually wrote a bit about this in the docs:
https://arktype.io/docs/faq#why-isnt-my-wrapper-generic-working