ianstormtaylor / superstruct

A simple and composable way to validate data in JavaScript (and TypeScript).
https://docs.superstructjs.org
MIT License
6.95k stars 224 forks source link

How can I generate declaration file from superstruct #1234

Closed hemedani closed 1 month ago

hemedani commented 3 months ago

I want to create .d.ts file from superstruct for example I want to convert:

const user = object({
    id: number(),
    name: string(),
  })

to

  type user = {
    id: number;
    name: string;
  };

And write it to a file with Node.js or Deno, but Infer<typeof user> does not available in runtime.

hemedani commented 3 months ago

This task was not very difficult. By writing a few helper functions, I was able to get the output I wanted. However, there is a serious problem. In Runtime, I did not find anything related to a field being optional. Actually, I have written a framework called Lesan with Superstruct. You can see the code I wrote to create the types here:

https://github.com/MiaadTeam/lesan/blob/main/src/types/generateTypesFromStruct.ts

Of course, this code has not been fully written yet.

But the problem is when we create an object with the following two fields:

object({
    optionalName: optional(string()),
    name: string(),
});

At runtime, we get something like this:

{
    "type": "object",
    "schema": {
        "optionalName": {
            "type": "string",
            "schema": null,
        },
        "name": {
            "type": "string",
            "schema": null,
        },
    },
}

I don't see anything related to the optionalName field being optional! While, we have put it in the optional(string()) function.
How should I know at runtime if a field is optional?
Finally, the type I create for the above struct is as follows:

{
    optionalName: string;
    name: string;
}

which I want to create it like this:

{
    optionalName?: string;
    name: string;
}
michalCapo commented 2 months ago
typeof user.TYPE
hemedani commented 1 month ago

Completed, but how? Please give a brief explanation. thanks a lot

michalCapo commented 1 month ago
import { number, object, optional, string } from "superstruct";

const user = object({
    id: number(),
    name: string(),
    some: optional(string()),
});

console.log(user.schema.name.validate(undefined)[0] == null) // false
console.log(user.schema.some.validate(undefined)[0] == null) // true