Readme

@skmtc/gen-typescript

Coverage

OpenAPI to TypeScript type definitions generator for Skmtc.

Supported Features

  • Primitive types: string, number, integer, boolean, null, unknown
  • Complex types: object, array, union (oneOf/anyOf), references ($ref)
  • Modifiers: nullable, optional properties, required properties
  • Enums: Single values (literals) and multiple values (unions)
  • Objects: Nested objects, empty objects, properties with special characters
  • Additional properties: Record types, mixed with regular properties
  • Arrays: Typed arrays, nested arrays, arrays of objects
  • References: Schema references including recursive types
  • Name transformations: kebab-case and snake_case to PascalCase

Getting started

Install Skmtc

deno install -g -A --unstable-worker-options jsr:@skmtc/cli -n skmtc -f

Skmtc runs on Deno. You can install it using

  • curl -fsSL https://deno.land/install.sh | sh on MacOS/Linux
  • irm https://deno.land/install.ps1 | iex on Windows

Create project and generate artifacts using TUI

skmtc

Create project and generate artifacts using CLI

# Create project
skmtc init <project name>

# Install TypeScript generator
skmtc install @skmtc/gen-typescript <project name>

# Bundle generator code
skmtc bundle <project name>

# Generate artifacts from OpenAPI schema
skmtc generate <project name> <path or url to openapi schema>

Usage Examples

Basic Primitive Types

Input (OpenAPI Schema)TypeScript
{
  "components": {
    "schemas": {
      "User": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "age": { "type": "number" },
          "score": { "type": "integer" },
          "isActive": { "type": "boolean" }
        },
        "required": ["id", "age", "score", "isActive"]
      }
    }
  }
}
export type User = {
  id: string,
  age: number,
  score: number,
  isActive: boolean
}

Optional Properties

Properties not in the required array become optional:

Input (OpenAPI Schema)TypeScript
{
  "Profile": {
    "type": "object",
    "properties": {
      "username": { "type": "string" },
      "bio": { "type": "string" },
      "website": { "type": "string" }
    },
    "required": ["username"]
  }
}
export type Profile = {
  username: string,
  bio?: string | undefined,
  website?: string | undefined
}

String Enums and Literal Unions

Single enum values become literals, multiple values become unions:

Input (OpenAPI Schema)TypeScript
{
  "Status": {
    "type": "string",
    "enum": ["active", "inactive", "pending"]
  },
  "Role": {
    "type": "string",
    "enum": ["admin"]
  }
}
export type Status = 'active' | 'inactive' | 'pending'
export type Role = 'admin'

Arrays

Input (OpenAPI Schema)TypeScript
{
  "Tags": {
    "type": "array",
    "items": { "type": "string" }
  },
  "Matrix": {
    "type": "array",
    "items": {
      "type": "array",
      "items": { "type": "number" }
    }
  }
}
export type Tags = Array<string>
export type Matrix = Array<Array<number>>

Nested Objects

Input (OpenAPI Schema)TypeScript
{
  "Company": {
    "type": "object",
    "properties": {
      "name": { "type": "string" },
      "address": {
        "type": "object",
        "properties": {
          "street": { "type": "string" },
          "city": { "type": "string" }
        },
        "required": ["street", "city"]
      }
    },
    "required": ["name", "address"]
  }
}
export type Company = {
  name: string,
  address: {
    street: string,
    city: string
  }
}

Nullable Types

Input (OpenAPI Schema)TypeScript
{
  "Article": {
    "type": "object",
    "properties": {
      "title": { "type": "string" },
      "publishedAt": {
        "type": "string",
        "nullable": true
      }
    },
    "required": ["title", "publishedAt"]
  }
}
export type Article = {
  title: string,
  publishedAt: string | null
}

Union Types

Input (OpenAPI Schema)TypeScript
{
  "StringOrNumber": {
    "anyOf": [
      { "type": "string" },
      { "type": "number" }
    ]
  },
  "Pet": {
    "oneOf": [
      {
        "type": "object",
        "properties": {
          "type": { "type": "string", "enum": ["cat"] },
          "meow": { "type": "boolean" }
        },
        "required": ["type", "meow"]
      },
      {
        "type": "object",
        "properties": {
          "type": { "type": "string", "enum": ["dog"] },
          "bark": { "type": "boolean" }
        },
        "required": ["type", "bark"]
      }
    ]
  }
}
export type StringOrNumber = string | number

export type Pet = {
  type: 'cat',
  meow: boolean
} | {
  type: 'dog',
  bark: boolean
}

Record Types (Additional Properties)

Input (OpenAPI Schema)TypeScript
{
  "Metadata": {
    "type": "object",
    "additionalProperties": { "type": "string" }
  },
  "Config": {
    "type": "object",
    "properties": {
      "id": { "type": "string" }
    },
    "required": ["id"],
    "additionalProperties": { "type": "number" }
  }
}
export type Metadata = Record<string, string>

export type Config = {id: string} | Record<string, number>

References and Recursive Types

Input (OpenAPI Schema)TypeScript
{
  "Category": {
    "type": "object",
    "properties": {
      "name": { "type": "string" },
      "parent": { "$ref": "#/components/schemas/Category" }
    },
    "required": ["name"]
  }
}
export type Category = {
  name: string,
  parent?: Category | undefined
}

Type Name Transformations

Schema names are automatically converted to PascalCase:

Input (OpenAPI Schema)TypeScript
{
  "user-profile": { "type": "string" },
  "api_response": { "type": "number" },
  "MyType": { "type": "boolean" }
}
export type UserProfile = string
export type ApiResponse = number
export type MyType = boolean

Empty Objects

Input (OpenAPI Schema)TypeScript
{
  "EmptyObject": {
    "type": "object"
  }
}
export type EmptyObject = Record<string, unknown>

Testing

Run tests for this generator:

cd gen-typescript && deno task test

Or with coverage:

deno task test:coverage

Generate HTML coverage report:

deno task coverage:html

Support

License

MIT.