Перейти к содержимому
Tutorial

Хватит писать интерфейсы TypeScript вручную: сгенерируйте их автоматически из JSON.

| 5 min read

Используйте API Botoi JSON to TypeScript для создания точных интерфейсов TypeScript и схем Zod из любых полезных данных JSON в одном запросе POST.

TypeScript interface definition in an editor
Photo by Safar Safarov on Unsplash

Каждый раз, когда вы интегрируете новый API, вы в конечном итоге смотрите на ответ JSON и вручную набираете интерфейс. Поле за полем. Угадайте, какие значения являются необязательными. Забыв об этом created_at это строка, а не дата. Копирование документов, которые могут соответствовать реальному ответу, а могут и не соответствовать.

Это утомительно, медленно и является надежным источником ошибок. JSON уже содержит все необходимые вам типы. Их можно извлечь с помощью одного вызова API.

Один POST-запрос, один интерфейс TypeScript.

Отправьте любой объект JSON в Botoi json-to-typescript конечная точка с именем корневого интерфейса. API возвращает полный интерфейс TypeScript в виде строки.

curl -X POST https://api.botoi.com/v1/schema/json-to-typescript \\
  -H "Content-Type: application/json" \\
  -d '{
    "json": {
      "id": 1,
      "name": "Acme Corp",
      "active": true,
      "tags": ["saas", "b2b"]
    },
    "name": "Company"
  }'

Ответ:

{
  "success": true,
  "data": {
    "typescript": "interface Company {\\n  id: number;\\n  name: string;\\n  active: boolean;\\n  tags: string[];\\n}",
    "name": "Company"
  }
}

Сгенерированный интерфейс в формате:

interface Company {
  id: number;
  name: string;
  active: boolean;
  tags: string[];
}

API делает вывод number, string, boolean, и string[] из ценностей. Никаких ручных аннотаций. Никаких догадок.

Создайте скрипт типов из API для своего проекта.

Ввод интерфейсов вручную — это единоразовое решение. Лучший подход: скрипт, который получает живые ответы API. и генерирует файлы типов, которые вы можете зафиксировать в своем репозитории.

Вот скрипт bash, который генерирует типы TypeScript из любого URL-адреса:

#!/bin/bash
set -euo pipefail

API="https://api.botoi.com/v1/schema/json-to-typescript"
OUT_DIR="./src/types/generated"
mkdir -p "\$OUT_DIR"

generate_type() {
  local url="\$1"
  local name="\$2"
  local file="\$3"

  echo "Fetching \$url ..."
  local json
  json=\$(curl -s "\$url")

  echo "Generating \$name interface..."
  local result
  result=\$(curl -s -X POST "\$API" \\
    -H "Content-Type: application/json" \\
    -d "{\"json\": \$json, \"name\": \"\$name\"}")

  echo "\$result" | jq -r '.data.typescript' > "\$OUT_DIR/\$file"
  echo "Wrote \$OUT_DIR/\$file"
}

generate_type "https://api.github.com/users/octocat" "GitHubUser" "github-user.ts"
generate_type "https://jsonplaceholder.typicode.com/posts/1" "BlogPost" "blog-post.ts"

echo "Done. All types written to \$OUT_DIR/"

Запустите этот скрипт во время разработки или в качестве перехватчика перед фиксацией. При изменении вышестоящего API перезапустите сценарий, и ваши типы останутся точными.

Если вы предпочитаете Node.js bash:

import { writeFileSync, mkdirSync } from "fs";

const API = "https://api.botoi.com/v1/schema/json-to-typescript";

async function generateType(json: unknown, name: string): Promise<string> {
  const res = await fetch(API, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ json, name }),
  });
  const data = await res.json();
  return data.data.typescript;
}

async function main() {
  const userRes = await fetch("https://api.github.com/users/octocat");
  const userJson = await userRes.json();

  const typescript = await generateType(userJson, "GitHubUser");

  mkdirSync("./src/types/generated", { recursive: true });
  writeFileSync("./src/types/generated/github-user.ts", typescript);
  console.log("Wrote ./src/types/generated/github-user.ts");
}

main();

Реальный пример: генерация типов для ответа пользователя GitHub API

GitHub /users/:username конечная точка возвращает более 30 полей. Написание этого интерфейса вручную занимает минуты и допускает опечатки. Вот двухэтапный подход:

# Fetch the GitHub user JSON
GITHUB_JSON=\$(curl -s https://api.github.com/users/octocat)

# Send it to the Botoi API
curl -s -X POST https://api.botoi.com/v1/schema/json-to-typescript \\
  -H "Content-Type: application/json" \\
  -d "{\"json\": \$GITHUB_JSON, \"name\": \"GitHubUser\"}" \\
  | jq -r '.data.typescript'

Выход:

interface GitHubUser {
  login: string;
  id: number;
  node_id: string;
  avatar_url: string;
  gravatar_id: string;
  url: string;
  html_url: string;
  followers_url: string;
  following_url: string;
  gists_url: string;
  starred_url: string;
  subscriptions_url: string;
  organizations_url: string;
  repos_url: string;
  events_url: string;
  received_events_url: string;
  type: string;
  site_admin: boolean;
  name: string;
  company: string;
  blog: string;
  location: string;
  bio: string;
  twitter_username: string;
  public_repos: number;
  public_gists: number;
  followers: number;
  following: number;
  created_at: string;
  updated_at: string;
}

Это 32 поля, набранных правильно, менее чем за секунду. Перенаправьте вывод в файл, и у вас есть готовое к использованию определение типа.

Вместо этого сгенерируйте схемы Zod

Интерфейсы TypeScript обеспечивают безопасность во время компиляции, но они исчезают во время выполнения. Если вам нужна проверка времени выполнения, тот json-to-zod конечная точка генерирует схему Zod из того же входного JSON.

curl -s -X POST https://api.botoi.com/v1/schema/json-to-zod \\
  -H "Content-Type: application/json" \\
  -d '{
    "json": {
      "id": 1,
      "name": "Acme Corp",
      "active": true,
      "tags": ["saas", "b2b"]
    },
    "name": "Company"
  }' | jq -r '.data.zod'

Выход:

import { z } from "zod";

const Company = z.object({
  id: z.number(),
  name: z.string(),
  active: z.boolean(),
  tags: z.array(z.string()),
});

Перетащите сгенерированную схему в свою кодовую базу, и вы получите как проверку времени выполнения, так и вывод типа:

import { z } from "zod";

const Company = z.object({
  id: z.number(),
  name: z.string(),
  active: z.boolean(),
  tags: z.array(z.string()),
});

type Company = z.infer<typeof Company>;

const parsed = Company.parse(apiResponse);
// parsed is fully typed and validated at runtime

При использовании Zod неверные данные выбрасываются на границу вместо того, чтобы вызывать тихие ошибки глубоко в логике вашего приложения.

Когда использовать каждую конечную точку

Сценарий Конечная точка Почему
Внутренние ответы API, которым вы доверяете json-to-typescript Легкий; нет затрат на выполнение
Ответы внешнего API json-to-zod Проверяет данные на границе
Входные данные формы или данные, отправленные пользователем json-to-zod Разбирать, не проверять
Быстрое прототипирование json-to-typescript Самый быстрый путь к напечатанному коду
Генерация типа конвейера CI Или Оба производят детерминированный результат

Ключевые моменты

  • Один запрос заменяет ручной ввод. Отправьте JSON, получите обратно интерфейс TypeScript или схему Zod.
  • Автоматизируйте это. Добавьте в свой проект скрипт, который восстанавливает типы при каждом изменении исходных API.
  • Никакой учетной записи не требуется. Уровень бесплатного пользования допускает 5 запросов в минуту без регистрации.
  • Работает с любым источником JSON. REST API, файлы конфигурации, экспорт баз данных, полезные данные веб-перехватчика.

The полная документация по API обложка дополнительные конечные точки схемы, включая json-to-jsonschema для вывода схемы JSON.

FAQ

Какие структуры JSON поддерживает API?
API обрабатывает вложенные объекты, массивы, массивы смешанного типа, значения NULL и глубоко вложенные структуры. Он определяет правильный тип TypeScript для каждого значения, включая необязательные поля, если присутствует значение null.
Нужен ли мне ключ API?
Нет. Анонимный доступ разрешен со скоростью 5 запросов в минуту с ограничением скорости на основе IP. Для большего объема зарегистрируйтесь для получения ключа API на сайте botoi.com/api.
Могу ли я генерировать схемы Zod вместо интерфейсов TypeScript?
Да. Отправьте то же тело JSON на POST https://api.botoi.com/v1/schema/json-to-zod, и вы получите строку схемы Zod, которую можно добавить в свой проект.
Как API обрабатывает массивы смешанных типов?
Если массив содержит значения разных типов, API создает тип объединения. Например, массив со строками и числами принимает вид (строка | число)[].
Могу ли я использовать это в конвейере CI?
Да. API представляет собой стандартную конечную точку HTTP POST. Вызовите его из любого сценария оболочки, действия GitHub или этапа сборки, чтобы синхронизировать определения типов с ответами вышестоящего API.

Начните разработку с botoi

150+ API-эндпоинтов для поиска, обработки текста, генерации изображений и утилит для разработчиков. Бесплатный тариф, без банковской карты.