question about arktype => TS
I'm building OSS tooling for event-driven architecture and I have a question about ArkType, I'm currently using zod but I find it a bit cumbersome as I have to add 2 external packages to achieve what I'm doing. For some context I'm building over the wire typesafety and typegen, how I achieve this is I take in a schema, I turn that schema into a string representation of the type, then I send that over an event bus to all the other apps which listen to that event and then there I write it to the filesystem if it's local development.
The current approach is this:
I would like to make it more "typescript-y and json-y" where you don't have to install zod into every app that consumes this class and pass in the schema, but rather for it to feel very intuitive and easy to write and I can then move this into the class itself. I think ArkType is the closest and most intuitive solution for this so I'd like to see how you guys would go about achieving this?
30 Replies
@TizzySaurus here you go
i've looked into this:
https://arktype.io/docs/blog/2.1
and toJsonTsPattern("foo") feels like a very close thing to what i'm trying to do
Is there a specific reason it has be a TypeScript string?
E.g. could you just send
MyType.toJSONSchema()
(assuming there's never morphs/narrows/etc.)?I need to write it to an actual file to overwrite the types
here is the end result of it
events.ts file:
So? Just write an array of json schemas that you parse
then this gets registered like:
If you havethen you can parse those in to arktype types via
@ark/json-schema
and do t["infer"]
to get the TypeScript type
And I think it's possible to add annotations (e.g. a name for the event or w/e)just so I'm clear, you mean I write the JSON schemas into the files, then I use the infer from ark to convert them into types?
I think so, yeah
Write JSON to file -> read JSON file -> parse each schema with
@ark/json-schema
npm package -> use t["infer"]
on each parsed schemaahh okay, so what I'm trying to do is create a 0 dep flow
where I would hopefully use arktype to get a TS only types and write them there, so the user himself doesn't have to install arktype/anything else in the consumer apps
I mean what you're trying to do seems very much like an anti-pattern in my head
I still don't really understand the use case tbh
event-driven arch. is usually used to link multiple org applications together through an event-bus with events, I'm trying to make them typesafe so instead of being able to subscribe to "event.anything" it narrows down the type to actual events, and in order to make the payloads typesafe I use schemas to describe what the payload can look like. so if you have app A, then apps B & C can send the payload to the event as described in app A without having access to that apps types (in certain cases where users don't use monorepos etc)
Ideally I'd like the user to not have to install additional deps in apps A/B/C to make it work
Really you should be validating shapes at every boundary
So when B sends the payload, whoever receives it should be validating
Is there actually a code-enforced guarantee that the payload B sends has to match a certain shape? Because if there's not then what you're trying just doesn't make sense (you're trying to add type-safety in a scenario where there is inherently none)
( @alle00 )
there is, the tool we created handles the encoding/decoding of data
so you're guaranteed you'll get the data you expect
it's not "just types"
I send the json schema as well and then I parse the data on the other side with the matching schema to make sure it works
So infer the type from the json schema then?
Writing TS types to a file is just a massive anti-pattern in my head, and I highly doubt that's actually the best approach
I mean, it's almost identical in terms of approach to react-router v7 type-safety features, I don't think inference would work in these scenarios but i'll have to check 🤔
Yeah inference might not work tbf, because you don't know the type of the json schema
it just requires a typegen step that writes it and overrides it, it's not unsafe because the other things i do under the hood guarantee the types
plus there are wildcard combinations
you could do user.* which subscribes you to 5 different events
The general approach for this afaik would be to create a shared package between A & B & C so that all of them have all the types. Which I guess is sorta what you're trying to do by writing TS types to a file...
it's kind of similar to prisma generate, if that's the easier way to think abouti t
I'm not familiar with that 🙈
First-class support for optimized .d.ts would be something I'd be interested in eventually, though it would be complex to do well and isn't the top priority at the moment.
.expression
is the closest you'd get as an interim solution.
You could strip out extra constraints first if you wanted to align with TS as closely as possible (though it would be tricky to do without knowledge of some internal APIs)I'll check it out, I'm also looking into standard schema and the .types property, looks really interesting as well
Standard Schema is a thin validation wrapper with some static-only props attached for inference so that definitely won't help
You can just publish .d.ts from inferred arktype directly, but it will incur extra overhead of inference and can't represent certain types e.g. that are cyclic
My preferred solution is allowing the user to bring his own validation lib 😅
hmm I'll look into the
.expression
firstThere shouldn't be any reason you have to do any of this if all you want is for users to be able to provide a schema and you infer it and use it to provide type-safe APIs
unfortunately the type-safe APIs span across multiple apps and are usually separated by a network layer
There are advantages to generating the computed types directly, but it adds a lot of complexity and will be essentially impossible to do in a schema-agnostic way
it's a very rare edge case
yeah it seems that way unfortunately, the dream would be BYOSVL (schema validation lib), but that looks like an impossible solution atm
thank you boys for the time and talking to me! really appreciated!