type-generation

Type Generation - Quick Reference

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "type-generation" with this command: npx skills add claude-dev-suite/claude-dev-suite/claude-dev-suite-claude-dev-suite-type-generation

Type Generation - Quick Reference

When NOT to Use This Skill

  • Manual type writing - Use TypeScript skills

  • Contract validation - Use openapi-contract skill

  • GraphQL queries - Use graphql-contract skill

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: typescript for advanced type patterns.

Tool Comparison

Tool Source Output Use Case

openapi-typescript OpenAPI 3.x TypeScript types REST APIs

openapi-fetch OpenAPI 3.x Type-safe client REST + fetch

graphql-codegen GraphQL schema Types + hooks GraphQL APIs

orval OpenAPI 3.x Types + client REST + Axios/fetch

swagger-typescript-api OpenAPI/Swagger Types + class client REST APIs

openapi-typescript Setup

Installation

npm install -D openapi-typescript

Basic Usage

From local file

npx openapi-typescript openapi.yaml -o src/api/types.ts

From URL

npx openapi-typescript https://api.example.com/openapi.json -o src/api/types.ts

Watch mode

npx openapi-typescript openapi.yaml -o src/api/types.ts --watch

Configuration (openapi-ts.config.ts)

import { defineConfig } from 'openapi-typescript';

export default defineConfig({ input: './openapi.yaml', output: './src/api/types.ts', // Alphabetize output alphabetize: true, // Export type for each path exportType: true, // Transform property names transform: (schemaObject) => { // Custom transformation return schemaObject; }, });

Generated Types Usage

// Generated types import type { paths, components } from './api/types';

// Request body type type CreateUserBody = paths['/users']['post']['requestBody']['content']['application/json'];

// Response type type UserResponse = paths['/users']['get']['responses']['200']['content']['application/json'];

// Schema type type User = components['schemas']['User'];

// Path parameters type UserParams = paths['/users/{id}']['parameters']['path'];

openapi-fetch Setup (Type-safe Client)

Installation

npm install openapi-fetch npm install -D openapi-typescript

Generate Types + Create Client

Generate types first

npx openapi-typescript openapi.yaml -o src/api/types.ts

// src/api/client.ts import createClient from 'openapi-fetch'; import type { paths } from './types';

const client = createClient<paths>({ baseUrl: 'https://api.example.com', headers: { 'Content-Type': 'application/json', }, });

export default client;

Usage with Type Safety

import client from './api/client';

// GET request - fully typed const { data, error } = await client.GET('/users/{id}', { params: { path: { id: '123' }, query: { include: 'profile' }, }, });

if (data) { // data is properly typed as User console.log(data.name); }

// POST request const { data: newUser } = await client.POST('/users', { body: { name: 'John', email: 'john@example.com', }, });

// With React Query import { useQuery, useMutation } from '@tanstack/react-query';

function useUser(id: string) { return useQuery({ queryKey: ['user', id], queryFn: async () => { const { data, error } = await client.GET('/users/{id}', { params: { path: { id } }, }); if (error) throw error; return data; }, }); }

GraphQL Codegen Setup

Installation

npm install -D @graphql-codegen/cli @graphql-codegen/typescript
@graphql-codegen/typescript-operations @graphql-codegen/typescript-react-query

Configuration (codegen.ts)

import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = { schema: 'https://api.example.com/graphql', documents: ['src//*.graphql', 'src//*.tsx'], generates: { './src/generated/graphql.ts': { plugins: [ 'typescript', 'typescript-operations', 'typescript-react-query', ], config: { fetcher: { endpoint: 'https://api.example.com/graphql', }, exposeQueryKeys: true, exposeFetcher: true, }, }, }, };

export default config;

GraphQL Document

src/graphql/users.graphql

query GetUser($id: ID!) { user(id: $id) { id name email createdAt } }

mutation CreateUser($input: CreateUserInput!) { createUser(input: $input) { id name email } }

Generate and Use

npx graphql-codegen

// Auto-generated hooks import { useGetUserQuery, useCreateUserMutation } from './generated/graphql';

function UserProfile({ userId }: { userId: string }) { const { data, isLoading } = useGetUserQuery({ id: userId });

if (isLoading) return <Spinner />; return <div>{data?.user?.name}</div>; }

function CreateUserForm() { const mutation = useCreateUserMutation();

const onSubmit = (data: CreateUserInput) => { mutation.mutate({ input: data }); };

return <form onSubmit={handleSubmit(onSubmit)}>...</form>; }

Orval Setup (OpenAPI + Client Generation)

Installation

npm install -D orval

Configuration (orval.config.ts)

import { defineConfig } from 'orval';

export default defineConfig({ petstore: { input: './openapi.yaml', output: { target: './src/api/endpoints.ts', schemas: './src/api/model', client: 'react-query', mode: 'tags-split', mock: true, }, }, });

Generate

npx orval

Generated Output

// Auto-generated hooks with React Query import { useGetUsers, useCreateUser } from './api/endpoints';

function UserList() { const { data: users } = useGetUsers(); return <ul>{users?.map(u => <li key={u.id}>{u.name}</li>)}</ul>; }

Package.json Scripts

{ "scripts": { "generate:types": "openapi-typescript openapi.yaml -o src/api/types.ts", "generate:client": "orval", "generate:graphql": "graphql-codegen", "generate": "npm run generate:types && npm run generate:client", "predev": "npm run generate", "prebuild": "npm run generate" } }

CI/CD Integration

GitHub Actions

name: Type Generation on: [push, pull_request]

jobs: generate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'

  - name: Install dependencies
    run: npm ci

  - name: Generate types
    run: npm run generate:types

  - name: Check for changes
    run: |
      git diff --exit-code src/api/types.ts || \
      (echo "Types are out of date! Run 'npm run generate:types'" &#x26;&#x26; exit 1)

Best Practices

  1. Version Control Generated Files

Option A: Don't commit (regenerate in CI)

src/api/types.ts src/generated/

Option B: Commit (recommended for visibility)

Don't add to .gitignore, commit generated files

  1. Pre-commit Hook

// package.json { "lint-staged": { "openapi.yaml": [ "npm run generate:types", "git add src/api/types.ts" ] } }

  1. Watch Mode in Development

{ "scripts": { "dev": "concurrently "npm run generate:types -- --watch" "vite"" } }

  1. Type Re-exports

// src/api/index.ts export type { User, CreateUserRequest, UpdateUserRequest, UserListResponse, } from './types';

export { default as client } from './client';

Common Patterns

Nullable Fields

OpenAPI

components: schemas: User: properties: middleName: type: string nullable: true

// Generated interface User { middleName: string | null; }

// Usage const displayName = user.middleName ?? 'N/A';

Discriminated Unions

OpenAPI

components: schemas: Shape: oneOf: - $ref: '#/components/schemas/Circle' - $ref: '#/components/schemas/Rectangle' discriminator: propertyName: type

// Generated type Shape = Circle | Rectangle;

// Usage with type narrowing function getArea(shape: Shape): number { switch (shape.type) { case 'circle': return Math.PI * shape.radius ** 2; case 'rectangle': return shape.width * shape.height; } }

Enums

OpenAPI

components: schemas: UserRole: type: string enum: [admin, user, guest]

// Generated as union type type UserRole = 'admin' | 'user' | 'guest';

// Or as const object const UserRole = { Admin: 'admin', User: 'user', Guest: 'guest', } as const;

Anti-Patterns

Anti-Pattern Why It's Bad Correct Approach

Manual type sync Drift, errors Auto-generate from spec

any for API responses No type safety Use generated types

Ignoring nullable Runtime errors Handle null properly

No pre-commit generation Outdated types Hook into git workflow

Editing generated files Lost on regenerate Extend types separately

Quick Troubleshooting

Issue Likely Cause Solution

Types don't match API Outdated spec Update and regenerate

Generation fails Invalid OpenAPI Validate spec first

Missing properties Optional vs required Check OpenAPI schema

Wrong enum values Spec changed Regenerate types

Import errors Path configuration Check tsconfig paths

Related Skills

  • OpenAPI Contract

  • GraphQL Contract

  • DTO Sync Patterns

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

cron-scheduling

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

token-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

webrtc

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

react-19

No summary provided by upstream source.

Repository SourceNeeds Review