TypeBox-Codegen

repository·main·Indexed 42 days ago

https://github.com/sinclairzx81/typebox-codegen

A toolset for transforming TypeScript types into TypeBox schemas and other validation library representations. It supports generating code for Zod, Valibot, Effect, ArkType, io-ts, Yup, and JSON Schema. Version 0.11.1 provides a two-stage workflow: mapping TypeScript source to an intermediate TypeBox Model, then generating specific target representations using generators like ModelToZod.Generate or ModelToValibot.Generate.

Tokens
3K
Snippets
13
Records
16
Agent score
52%

What's inside TypeBox-Codegen

  1. How TypeBox-Codegen works

    main

    TypeBox-Codegen operates in two main stages:

    1. Mapping: It maps structural type information from the TypeScript compiler into an intermediate TypeBox Model.
    2. Generation: This model is then passed to various code generators that use TypeBox schema introspection to produce code for different libraries or formats.

    Supported target representations include:

    • Schema Libraries: zod, effect, arktype, io-ts, and valibot.
    • Formats: JSON Schema.
    • Languages: JavaScript and TypeScript assertions.
  2. Use the two-stage generation workflow

    main

    For more complex workflows, you can separate the process into two steps: generating an in-memory model and then generating specific code from that model.

    1. Generate an in-memory model

    Use Codegen.TypeScriptToModel.Generate(code) to create a TypeBox Model from TypeScript source code.

    2. Generate specific representations from the model

    Pass the resulting model to various ModelToX generators:

    GeneratorTarget
    Codegen.ModelToJsonSchema.Generate(model)JSON Schema
    Codegen.ModelToJavaScript.Generate(model)JavaScript
    Codegen.ModelToTypeScript.Generate(model)TypeScript
    Codegen.ModelToValibot.Generate(model)Valibot
    Codegen.ModelToValue.Generate(model)Value
    Codegen.ModelToYup.Generate(model)Yup
    Codegen.ModelToZod.Generate(model)Zod
    Codegen.ModelToArkType.Generate(model)ArkType
    Codegen.ModelToEffect.Generate(model)Effect
    import * as Codegen from '@sinclair/typebox-codegen'
    
    const Code = `
    export type T = {
      x: number,
      y: number,
      z: number
    }
    `
    
    // 1. Generate the model
    const model = Codegen.TypeScriptToModel.Generate(Code)
    
    // 2. Generate specific outputs
    console.log('Zod:', Codegen.ModelToZod.Generate(model))
    console.log('JSON Schema:', Codegen.ModelToJsonSchema.Generate(model))
  3. Run TypeBox-Codegen locally

    main

    If you have cloned the repository, you can use the following npm scripts:

    • npm install: Install dependencies.
    • npm format: Run Prettier on src and example directories.
    • npm clean: Remove the target directory.
    • npm start: Run the example script in Node.
    $ npm install
    $ npm format
    $ npm clean
    $ npm start
  4. Transform TypeScript types to TypeBox code

    main

    Use Codegen.TypeScriptToTypeBox.Generate to perform an immediate transformation from a TypeScript type string directly into TypeBox schema code. This is the simplest way to convert TypeScript definitions into TypeBox Type objects.

    import * as Codegen from '@sinclair/typebox-codegen'
    
    const Code = Codegen.TypeScriptToTypeBox.Generate(`
      type T = { x: number, y: number, z: number }
    `)
    
    console.log(Code)
    
    // Output:
    //
    // import { Type, Static } from '@sinclair/typebox'
    // 
    // type T = Static<typeof T>
    // const T = Type.Object({
    //   x: Type.Number(),
    //   y: Type.Number(),
    //   z: Type.Number()
    // })
  5. Configure TypeScriptToTypeBoxOptions

    main

    When calling TypeScriptToTypeBox.Generate, you can provide an options object to customize the output:

    OptionTypeDefaultDescription
    useExportEverythingbooleanfalseIf true, ensures all types are exported as const values. Useful for gathering definitions during runtime evaluation.
    useTypeBoxImportbooleantrueSpecifies if the output should include a default import { ... } from '@sinclair/typebox' statement.
    useIdentifiersbooleanfalseIf true, includes an identifier (using $id) associated with the assigned variable name. This creates a referential type model instead of an inline model.
  6. Configure ModelToValibotSettings

    main

    When calling ModelToValibot.Generate, you can provide an options object of type ModelToValibotSettings to control the output format of optional properties.

    OptionTypeDefaultDescription
    exactOptionalPropertyTypesbooleanfalseIf true, optional properties in objects are generated using v.exactOptional(). If false, they use v.optional().
    export interface ModelToValibotSettings {
      exactOptionalPropertyTypes: boolean
    }
  7. Handle TypeScriptToTypeBoxError

    main

    If the generated code fails to transpile (e.g., due to syntax errors in the input or the generated output), the library throws a TypeScriptToTypeBoxError. This error contains a diagnostics array from the TypeScript compiler which can be used to debug the issue.

    try {
      TypeScriptToTypeBox.Generate(invalidTsCode);
    } catch (error) {
      if (error instanceof TypeScriptToTypeBoxError) {
        console.error('Diagnostics:', error.diagnostics);
      }
    }
  8. Extract exports from generated TypeBox code

    main

    The TypeScriptToModel.Exports function evaluates generated TypeBox code strings using a Function constructor to extract exported variables. It injects Type, Kind, and CloneType from @sinclair/typebox into the evaluation scope so that the generated code can execute correctly.

    Note: This function uses eval-like behavior via new Function to resolve the generated code into a runtime object.

    import { TypeScriptToModel } from '@sinclair/typebox-codegen';
    
    const code = `exports.MySchema = Type.String();`;
    const exports = TypeScriptToModel.Exports(code);
    // returns { MySchema: TSchema }
  9. Generate JavaScript object representations using ModelToJavaScript.Generate

    main

    The ModelToJavaScript.Generate function converts a TypeBoxModel into a string containing JavaScript code. The generated code uses an Immediately Invoked Function Expression (IIFE) for each type in the model to export constant definitions. Each definition is prefixed with // @ts-nocheck to prevent TypeScript type-checking errors in the generated output. The core logic relies on @sinclair/typebox/compiler's TypeCompiler.Code method with the language: 'javascript' option.

    import { ModelToJavaScript } from './path-to-this-module';
    
    // Assuming 'model' is a valid TypeBoxModel instance
    const jsCode = ModelToJavaScript.Generate(model);
    console.log(jsCode);
  10. Generate Valibot schema code from TypeBox models

    main

    The ModelToValibot.Generate function converts a TypeBoxModel into a string containing Valibot schema definitions and TypeScript types. It automatically handles imports, type inference, and recursive schemas using v.lazy.

    import { ModelToValibot } from '@sinclair/typebox-codegen';
    
    // Assuming 'model' is a valid TypeBoxModel instance
    const valibotCode = ModelToValibot.Generate(model, {
      exactOptionalPropertyTypes: true
    });