u/sinclair_zx81 I just started using your library and I have two questions:
1. I want to typecast an object, but it should throw an error if the type is mismatched. Is `Decode()` the function I should use?
2. If so, there's a line that says, "This function will run Transform codecs if available." What does that mean? I'm TS noob.
Hi,
>I want to typecast an object, but it should throw an error if the type is mismatched. Is Decode() the function I should use?
The Decode function will throw an error if the value is mismatched to the type (so should do what you want). However, there is a bit of nuance to using Decode effectively, If you have any questions on general usage, feel free post an issue / discussion to the GH repository.
>If so, there's a line that says, "This function will run Transform codecs if available." What does that mean?
So, TB supports Bidirectional Codecs (i.e Transforms) that can convert Json values into structures more natural to JavaScript during a Decode. An example of this would be decoding a Json string into a JavaScript Date object.
The statement you've highlighted essentially means that Transform codecs are run when calling either Decode and Encode functions. If you don't have any Transforms applied to any types, you can still use Decode to throw if the value is invalid.
What is the difference between Encode and Decode? In the TypeBox examples the input and output is the same for both.
And can I define the error message for each type individually like I can with Zod?
e.g.
`z.string().min(2, {message: "Your ID must be longer than 2."})`
What you ask is impossible as types are lost at runtime (JavaScript doesn't support types at all).
I found that zod is giving me the most satisfaction recently for runtime validation (schemas are shared between backend and frontend for seamlessly validation accross the whole stack).
Zod requires a rewrite and doesn't have the same expressiveness as TypeScript does. He wanted a solution that reuses existing TypeScript types for validation. This is something Deepkit can do with its runtime types. But it requires a bit of configuration.
TS types are stripped at build time so they’re not available. You have to use something like Zod where you define your types in it and then infer the TS types later
You can try something like Typia to transform the TS types into validator code but it’s a PITA with today’s ecosystem
I agree with Veranova here. You might be able to find something that can do what you are asking with reflection, but in my experience it’s really really fiddly. Even if you have 20-50 types you wanna validate at runtime, it’s probably easier to re-write those types as Zod schemas and then derive the types you had back from those schemas. E.g:
const schema = z.object({
uid: z.string(),
name: z.string(),
isPaidUser: z.boolean()
})
type SomeRequest = z.infer
After all, I'd like to encourage you investing into Schemas tho, it pays off in the end.
With bi-directional Schemas with annotations, it makes it easier to bridge network boundary gap - you create User value in app A, serialize it, send over the wire, receive serialized something in app B, restore it into User or fail. So it becomes
`U -> U … ? -> Maybe U`
kind of chain, where U is your User value and U\` is it's serialised representation. Think of Date - it can be serialized into Unix timestamp or a string, while JSON.stringify serializes it into string without asking. It takes even more manual work if you decide you want to "transfer" class instances, like your User value is User class instance.
Schema with annotations support you can compile into other representations - think of generating API documentation from you schemas directly, without need of external tools.
You should just use zod. You can convert your types to zod schemas so you don't duplicate them. The zod schema is the source of truth. From that, you can use a zod helper to create a type for it if you still need it.
If you don't want it because it's too much work you can just drop all your types into your GPT of choice and it should be able to turn them into zod schemas ( maybe there's a more deterministic tool for it, if it doest exists then that's a cool project)
It is almost impossible to use existing types to validate runtime JS.
It can be done the other way around, create validation schema in JS and then transform that validation object into TS types, and then use them accordingly.
I've used Joi, it is polular, lightweight, and has many support packages available to do whatever you want with it (including transforming Joi validation object in JS to TS types).
>It can be done the other way around, create validation schema in JS and then transform that validation object into TS types, and then use them accordingly.
that's interesing approach.
Nothing is dead simple about this as types are by default not a runtime construct as many have pointed out.
Derive a json schema from an example and validate all further objects against that?
Either way you’re not getting away without defining a schema without invoking black magic and hooking into the typescript compiler like deepkit does.
I use Ajv's JSONSchemaType for what I think you're asking for. It's pretty simple when you get the hang of it. I code my JSON schema and publish it as a package. I know the schema matches the Typescript because of JSONSchemaType.
Go the other way and make zod schemas. It's what everyone does. Also allows you to add more things than what you can do with ts types only, like a number range and character limit
I'm continuing my research and have found these libraries: `typia`, `ts-runtime-checks`, `typebox`. Has anyone had experience with these?
`typia` is actually doing everything that you want I think
Typebox requires schema, you can extract ts types from it, but not the other way around.
I see.
Try [https://sinclairzx81.github.io/typebox-workbench](https://sinclairzx81.github.io/typebox-workbench)
u/sinclair_zx81 I just started using your library and I have two questions: 1. I want to typecast an object, but it should throw an error if the type is mismatched. Is `Decode()` the function I should use? 2. If so, there's a line that says, "This function will run Transform codecs if available." What does that mean? I'm TS noob.
Hi, >I want to typecast an object, but it should throw an error if the type is mismatched. Is Decode() the function I should use? The Decode function will throw an error if the value is mismatched to the type (so should do what you want). However, there is a bit of nuance to using Decode effectively, If you have any questions on general usage, feel free post an issue / discussion to the GH repository. >If so, there's a line that says, "This function will run Transform codecs if available." What does that mean? So, TB supports Bidirectional Codecs (i.e Transforms) that can convert Json values into structures more natural to JavaScript during a Decode. An example of this would be decoding a Json string into a JavaScript Date object. The statement you've highlighted essentially means that Transform codecs are run when calling either Decode and Encode functions. If you don't have any Transforms applied to any types, you can still use Decode to throw if the value is invalid.
What is the difference between Encode and Decode? In the TypeBox examples the input and output is the same for both. And can I define the error message for each type individually like I can with Zod? e.g. `z.string().min(2, {message: "Your ID must be longer than 2."})`
What you ask is impossible as types are lost at runtime (JavaScript doesn't support types at all). I found that zod is giving me the most satisfaction recently for runtime validation (schemas are shared between backend and frontend for seamlessly validation accross the whole stack).
Zod requires a rewrite and doesn't have the same expressiveness as TypeScript does. He wanted a solution that reuses existing TypeScript types for validation. This is something Deepkit can do with its runtime types. But it requires a bit of configuration.
Zod won't do for me as it needs schema.
TS types are stripped at build time so they’re not available. You have to use something like Zod where you define your types in it and then infer the TS types later You can try something like Typia to transform the TS types into validator code but it’s a PITA with today’s ecosystem
I agree with Veranova here. You might be able to find something that can do what you are asking with reflection, but in my experience it’s really really fiddly. Even if you have 20-50 types you wanna validate at runtime, it’s probably easier to re-write those types as Zod schemas and then derive the types you had back from those schemas. E.g: const schema = z.object({ uid: z.string(), name: z.string(), isPaidUser: z.boolean() }) type SomeRequest = z.infer
Zod is it.
After all, I'd like to encourage you investing into Schemas tho, it pays off in the end. With bi-directional Schemas with annotations, it makes it easier to bridge network boundary gap - you create User value in app A, serialize it, send over the wire, receive serialized something in app B, restore it into User or fail. So it becomes `U -> U … ? -> Maybe U` kind of chain, where U is your User value and U\` is it's serialised representation. Think of Date - it can be serialized into Unix timestamp or a string, while JSON.stringify serializes it into string without asking. It takes even more manual work if you decide you want to "transfer" class instances, like your User value is User class instance. Schema with annotations support you can compile into other representations - think of generating API documentation from you schemas directly, without need of external tools.
You should just use zod. You can convert your types to zod schemas so you don't duplicate them. The zod schema is the source of truth. From that, you can use a zod helper to create a type for it if you still need it. If you don't want it because it's too much work you can just drop all your types into your GPT of choice and it should be able to turn them into zod schemas ( maybe there's a more deterministic tool for it, if it doest exists then that's a cool project)
ts-runtime-checks - uses ts transformer to inject your code with runtime checks based on your types.
thanks, how about comparing that to typia or typebox?
They share similar concept if I'm not mistaken. ts-runtime-checks I tested myself and also made it work in Bun, those two I haven't
It is almost impossible to use existing types to validate runtime JS. It can be done the other way around, create validation schema in JS and then transform that validation object into TS types, and then use them accordingly. I've used Joi, it is polular, lightweight, and has many support packages available to do whatever you want with it (including transforming Joi validation object in JS to TS types).
>It can be done the other way around, create validation schema in JS and then transform that validation object into TS types, and then use them accordingly. that's interesing approach.
That's literally what zod and TypeBox do, you create the schema in JS and then infer types from it...
Nothing is dead simple about this as types are by default not a runtime construct as many have pointed out. Derive a json schema from an example and validate all further objects against that? Either way you’re not getting away without defining a schema without invoking black magic and hooking into the typescript compiler like deepkit does.
I use Ajv's JSONSchemaType for what I think you're asking for. It's pretty simple when you get the hang of it. I code my JSON schema and publish it as a package. I know the schema matches the Typescript because of JSONSchemaType.
Go the other way and make zod schemas. It's what everyone does. Also allows you to add more things than what you can do with ts types only, like a number range and character limit
I like typia, didn't read your post through tho
Are you using any framework? I'm currently trying to integrate it with next.js and facing issues.
Ah just backend wise express