@skmtc/gen-typescript

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.