JSONからTypeScript型を生成する方法
JSONスキーマからTypeScript型定義を自動生成。ツール、技術、ベストプラクティス。
Big JSON Team
• Technical WriterExpert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.
# JSONからTypeScript型を生成する方法
JSONデータからTypeScript型定義を自動生成する方法を学びます。
なぜ型生成が必要か
利点
- ✅ 型安全性 - コンパイル時のエラー検出
- ✅ 自動補完 - IDEサポート
- ✅ ドキュメント - 型が仕様書になる
- ✅ リファクタリング - 安全な変更
- ✅ 時間節約 - 手動で書く必要なし
Before(型なし)
const user = JSON.parse(response);
console.log(user.name); // タイポの可能性
After(型あり)
interface User {
id: number;
name: string;
email: string;
}
const user: User = JSON.parse(response);
console.log(user.name); // 型安全
オンラインツール
1. QuickType
URL: quicktype.io 特徴:- 最も強力
- 複数言語サポート
- JSON、JSONスキーマから変換
- カスタマイズ可能
入力JSON:
{
"id": 1,
"name": "田中太郎",
"email": "tanaka@example.com",
"isActive": true
}
出力TypeScript:
export interface User {
id: number;
name: string;
email: string;
isActive: boolean;
}
2. JSON2TS
URL: json2ts.com 特徴:- シンプル
- ルートタイプ名のカスタマイズ
- プレフィックス/サフィックス
- プレフィックス追加(例: I)
- オプショナルプロパティ
- 読み取り専用
3. Transform Tools
URL: transform.tools/json-to-typescript 特徴:- クリーンなUI
- リアルタイム変換
- 複数フォーマット
4. BigJSON.online
JSONビューアーとしても型のヒントを提供。
CLIツール
1. quicktype (CLI)
インストール
npm install -g quicktype
基本的な使い方
# JSONファイルから型生成
quicktype data.json -o types.ts
# 複数ファイル
quicktype user.json product.json -o types.ts
# 標準入力から
echo '{"name":"太郎","age":30}' | quicktype -o User.ts
高度なオプション
# トップレベル名を指定
quicktype data.json --top-level User -o User.ts
# JSONスキーマから
quicktype schema.json --src-lang schema -o types.ts
# インターフェースではなくクラス
quicktype data.json --just-types -o types.ts
# readonly プロパティ
quicktype data.json --readonly -o types.ts
2. json-schema-to-typescript
インストール
npm install -g json-schema-to-typescript
使い方
json2ts -i schema.json -o types.d.ts
3. NPMスクリプト統合
{
"scripts": {
"generate-types": "quicktype src/data/.json -o src/types.ts",
"types:watch": "nodemon --watch src/data --exec npm run generate-types"
}
}
プログラムでの生成
Node.js スクリプト
const { quicktype, InputData, JSONSchemaInput } = require('quicktype-core');
async function generateTypes(jsonString, typeName) {
const jsonInput = new JSONSchemaInput(new InputData());
await jsonInput.addSource({
name: typeName,
schema: jsonString,
});
const inputData = new InputData();
inputData.addInput(jsonInput);
const result = await quicktype({
inputData,
lang: 'typescript',
rendererOptions: {
'just-types': 'true',
},
});
return result.lines.join('\n');
}
// 使用例
const json = JSON.stringify({
id: 1,
name: '田中太郎',
email: 'tanaka@example.com',
});
generateTypes(json, 'User').then(types => {
console.log(types);
});
TypeScriptコンパイラAPI
import as ts from 'typescript';
function jsonToInterface(json: any, interfaceName: string): string {
const properties: string[] = [];
for (const [key, value] of Object.entries(json)) {
const type = getTypeScriptType(value);
properties.push( ${key}: ${type};);
}
return interface ${interfaceName} {\n${properties.join('\n')}\n};
}
function getTypeScriptType(value: any): string {
if (value === null) return 'null';
if (Array.isArray(value)) {
if (value.length === 0) return 'any[]';
return ${getTypeScriptType(value[0])}[];
}
if (typeof value === 'object') {
return 'any'; // または再帰的に処理
}
return typeof value;
}
// 使用
const json = { id: 1, name: '田中', active: true };
console.log(jsonToInterface(json, 'User'));
JSONスキーマからの生成
スキーマ定義
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "User",
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "ユーザーID"
},
"name": {
"type": "string",
"minLength": 1
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 0
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": ["id", "name", "email"]
}
生成されるTypeScript
/*
User
/
export interface User {
/
ユーザーID
/
id: number;
name: string;
email: string;
age?: number;
tags?: string[];
}
json-schema-to-typescript使用
import { compile } from 'json-schema-to-typescript';
import as fs from 'fs';
const schema = JSON.parse(fs.readFileSync('user-schema.json', 'utf8'));
compile(schema, 'User', {
bannerComment: '',
style: {
semi: true,
singleQuote: true,
},
}).then(ts => {
fs.writeFileSync('User.d.ts', ts);
});
複雑な型の処理
ネストされたオブジェクト
入力:
{
"user": {
"id": 1,
"name": "田中太郎",
"address": {
"city": "東京",
"zip": "100-0001"
}
}
}
出力:
export interface Address {
city: string;
zip: string;
}
export interface User {
id: number;
name: string;
address: Address;
}
export interface RootObject {
user: User;
}
配列とジェネリクス
入力:
{
"users": [
{
"id": 1,
"name": "田中太郎"
}
],
"posts": [
{
"id": 1,
"title": "Hello"
}
]
}
出力:
export interface User {
id: number;
name: string;
}
export interface Post {
id: number;
title: string;
}
export interface RootObject {
users: User[];
posts: Post[];
}
ユニオン型
入力(異なる型の値):
{
"items": [
{"type": "text", "content": "Hello"},
{"type": "image", "url": "pic.jpg"}
]
}
出力:
export interface TextItem {
type: 'text';
content: string;
}
export interface ImageItem {
type: 'image';
url: string;
}
export type Item = TextItem | ImageItem;
export interface RootObject {
items: Item[];
}
VS Code統合
設定
{
"json.schemas": [
{
"fileMatch": ["data/.json"],
"url": "./schemas/data-schema.json"
}
]
}
タスク自動化
{
"version": "2.0.0",
"tasks": [
{
"label": "Generate Types",
"type": "shell",
"command": "quicktype",
"args": [
"src/data.json",
"-o",
"src/types.ts"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
APIレスポンスからの型生成
自動化スクリプト
import fetch from 'node-fetch';
import { quicktype } from 'quicktype-core';
import as fs from 'fs';
async function generateTypesFromAPI(url: string, typeName: string) {
// APIからデータ取得
const response = await fetch(url);
const data = await response.json();
// サンプルデータを保存
fs.writeFileSync('sample.json', JSON.stringify(data, null, 2));
// 型を生成
const types = await generateTypes(JSON.stringify(data), typeName);
// 型定義を保存
fs.writeFileSync(${typeName}.ts, types);
}
// 使用
generateTypesFromAPI(
'https://api.example.com/users',
'User'
);
Postman統合
ベストプラクティス
1. 適切な型名
// 良い
export interface User {
id: number;
name: string;
}
// 悪い
export interface Object1 {
id: number;
name: string;
}
2. オプショナルプロパティ
export interface User {
id: number;
name: string;
email: string;
phone?: string; // オプション
address?: Address;
}
3. 読み取り専用プロパティ
export interface User {
readonly id: number;
name: string;
email: string;
}
4. 厳格なnullチェック
export interface User {
id: number;
name: string;
bio: string | null; // 明示的にnullを許可
}
5. ドキュメントコメント
/*
ユーザー情報
/
export interface User {
/
一意のユーザーID
/
id: number;
/
ユーザーの表示名
/
name: string;
}
自動化ワークフロー
Git Hooks
#!/bin/bash
# .git/hooks/pre-commit
# JSONファイルが変更されたら型を再生成
for file in $(git diff --cached --name-only | grep '.json$'); do
if [ -f "$file" ]; then
quicktype "$file" -o "${file%.json}.ts"
git add "${file%.json}.ts"
fi
done
CI/CD統合
# .github/workflows/generate-types.yml
name: Generate Types
on:
push:
paths:
- '.json'
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
- name: Install quicktype
run: npm install -g quicktype
- name: Generate types
run: |
quicktype src/data/.json -o src/types.ts
- name: Commit changes
run: |
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add src/types.ts
git commit -m "Update generated types" || exit 0
git push
Watch モード
// watch-types.js
const chokidar = require('chokidar');
const { exec } = require('child_process');
const watcher = chokidar.watch('src/*/.json');
watcher.on('change', (path) => {
console.log(${path} が変更されました。型を再生成中...);
exec(quicktype ${path} -o ${path.replace('.json', '.ts')},
(error, stdout, stderr) => {
if (error) {
console.error(エラー: ${error});
return;
}
console.log('型の生成完了!');
}
);
});
console.log('JSONファイルを監視中...');
トラブルシューティング
問題1: 型が"any"になる
原因: JSONデータが不十分 解決:- より完全なサンプルデータを使用
- JSONスキーマを使用
- 手動で型を修正
問題2: ネストが深すぎる
解決:// 型を分割
export interface Address {
city: string;
}
export interface User {
address: Address;
}
問題3: 重複する型定義
解決:- 共通の型を抽出
- 型のエイリアスを使用
ツール比較
| ツール | CLI | API | スキーマ対応 | カスタマイズ |
|--------|-----|-----|-------------|-------------|
| QuickType | ✅ | ✅ | ✅ | ⭐⭐⭐⭐⭐ |
| json-schema-to-typescript | ✅ | ✅ | ✅ | ⭐⭐⭐⭐ |
| JSON2TS | ❌ | ❌ | ❌ | ⭐⭐ |
| Transform Tools | ❌ | ❌ | ❌ | ⭐⭐⭐ |
まとめ
クイックスタート
# オンライン
# quicktype.io にアクセス
# CLI
npm install -g quicktype
quicktype data.json -o types.ts
# Node.js
npm install quicktype-core
推奨ワークフロー
型生成で、TypeScriptプロジェクトの型安全性を向上させましょう!