← Вернуться к блогу

Конвертация JSON в TypeScript: Полное руководство

Научитесь конвертировать JSON в TypeScript интерфейсы и типы. Автоматическая генерация, инструменты и лучшие практики.

Big JSON Team12 мин чтенияprogramming
B

Big JSON Team

Technical Writer

Expert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.

12 мин чтения

# Конвертация JSON в TypeScript: Полное руководство

TypeScript предоставляет строгую типизацию для JavaScript, а JSON данные часто нуждаются в типизации для безопасной работы. В этом руководстве мы рассмотрим все способы конвертации JSON в TypeScript типы и интерфейсы.

Почему нужна типизация JSON?

Проблемы без типизации

// JavaScript/TypeScript без типов

const данные = JSON.parse(jsonString);

console.log(данные.имя); // Нет автодополнения

console.log(данные.вораст); // Опечатка не обнаружена!

С типизацией

interface Пользователь {

имя: string;

возраст: number;

email: string;

}

const данные: Пользователь = JSON.parse(jsonString);

console.log(данные.имя); // Автодополнение работает

console.log(данные.вораст); // Ошибка компиляции!

Ручная конвертация

Простой объект

JSON:

{

"id": 123,

"имя": "Иван Петров",

"email": "ivan@example.com",

"активен": true

}

TypeScript интерфейс:

interface Пользователь {

id: number;

имя: string;

email: string;

активен: boolean;

}

// Использование

const пользователь: Пользователь = {

id: 123,

имя: "Иван Петров",

email: "ivan@example.com",

активен: true

};

Вложенные объекты

JSON:

{

"пользователь": {

"имя": "Иван",

"возраст": 30,

"адрес": {

"город": "Москва",

"улица": "Тверская",

"дом": 10

}

}

}

TypeScript:

interface Адрес {

город: string;

улица: string;

дом: number;

}

interface ДанныеПользователя {

имя: string;

возраст: number;

адрес: Адрес;

}

interface Корень {

пользователь: ДанныеПользователя;

}

// Использование

const данные: Корень = {

пользователь: {

имя: "Иван",

возраст: 30,

адрес: {

город: "Москва",

улица: "Тверская",

дом: 10

}

}

};

Массивы

JSON:

{

"пользователи": [

{

"id": 1,

"имя": "Иван"

},

{

"id": 2,

"имя": "Мария"

}

]

}

TypeScript:

interface Пользователь {

id: number;

имя: string;

}

interface КоллекцияПользователей {

пользователи: Пользователь[];

}

// Или с использованием Array<T>

interface КоллекцияПользователейАльт {

пользователи: Array<Пользователь>;

}

Автоматическая генерация

Онлайн инструменты

QuickType

URL: quicktype.io Возможности:
  • Генерация TypeScript из JSON
  • Поддержка множества языков
  • Настройка стиля кода
  • Обработка сложных структур

Пример использования:

Входной JSON:

{

"продукт": {

"id": "P001",

"название": "Ноутбук",

"цена": 75000,

"характеристики": {

"процессор": "Intel Core i7",

"память": "16GB",

"накопитель": "512GB SSD"

},

"теги": ["электроника", "компьютеры"]

}

}

Сгенерированный TypeScript:

export interface Корень {

продукт: Продукт;

}

export interface Продукт {

id: string;

название: string;

цена: number;

характеристики: Характеристики;

теги: string[];

}

export interface Характеристики {

процессор: string;

память: string;

накопитель: string;

}

// Конвертация функции

export function toКорень(json: string): Корень {

return JSON.parse(json);

}

export function кореньToJson(value: Корень): string {

return JSON.stringify(value);

}

Transform Tools

URL: transform.tools/json-to-typescript

Быстрый онлайн конвертер с настройками:

  • Interface vs Type
  • Naming conventions
  • Optional properties

JSON2TS

URL: json2ts.com

Простой инструмент для быстрой конвертации.

VS Code расширения

Paste JSON as Code

Установка:
1. Extensions → Поиск "Paste JSON as Code"
  • Установить расширение
  • Использование:
    1. Скопировать JSON
    
  • Ctrl/Cmd + Shift + P
  • "Paste JSON as Code"
  • Выбрать язык (TypeScript)
  • Ввести имя типа
  • JSON to TS

    Другое популярное расширение для генерации TypeScript типов.

    Пакеты NPM

    json-to-ts

    npm install -g json-to-ts
    Использование:
    # Из файла
    

    json-to-ts data.json > types.ts

    # Из stdin

    echo '{"имя":"Иван","возраст":30}' | json-to-ts

    Программно:
    import { JsonToTS } from 'json-to-ts';
    
    

    const json = {

    имя: "Иван",

    возраст: 30,

    навыки: ["JavaScript", "TypeScript"]

    };

    const types = JsonToTS(json);

    console.log(types.join('

    '));

    Результат:

    interface RootObject {
    

    имя: string;

    возраст: number;

    навыки: string[];

    }

    Продвинутые техники

    Optional Properties

    JSON может иметь отсутствующие поля:

    [
    

    {

    "имя": "Иван",

    "email": "ivan@example.com",

    "телефон": "+7-999-123-4567"

    },

    {

    "имя": "Мария",

    "email": "maria@example.com"

    }

    ]

    TypeScript:

    interface Пользователь {
    

    имя: string;

    email: string;

    телефон?: string; // Опциональное поле

    }

    // Использование

    function обработатьПользователя(пользователь: Пользователь) {

    console.log(пользователь.имя);

    // Проверка существования

    if (пользователь.телефон) {

    console.log(пользователь.телефон);

    }

    }

    Union Types

    JSON с разными вариантами:

    {
    

    "результат": "успех",

    "данные": {...}

    }

    {

    "результат": "ошибка",

    "сообщение": "Что-то пошло не так"

    }

    TypeScript:

    interface Успех {
    

    результат: "успех";

    данные: any;

    }

    interface Ошибка {

    результат: "ошибка";

    сообщение: string;

    }

    type АпиОтвет = Успех | Ошибка;

    // Использование с type guard

    function обработатьОтвет(ответ: АпиОтвет) {

    if (ответ.результат === "успех") {

    // TypeScript знает, что это Успех

    console.log(ответ.данные);

    } else {

    // TypeScript знает, что это Ошибка

    console.error(ответ.сообщение);

    }

    }

    Generics

    Для повторно используемых структур:

    interface АпиОтвет<T> {
    

    статус: "успех" | "ошибка";

    данные?: T;

    ошибка?: string;

    метаданные: {

    timestamp: string;

    версия: string;

    };

    }

    interface Пользователь {

    id: number;

    имя: string;

    }

    interface Продукт {

    id: string;

    название: string;

    цена: number;

    }

    // Использование

    const ответПользователя: АпиОтвет<Пользователь> = {

    статус: "успех",

    данные: {

    id: 1,

    имя: "Иван"

    },

    метаданные: {

    timestamp: "2026-01-26T10:00:00Z",

    версия: "2.0"

    }

    };

    const ответПродукта: АпиОтвет<Продукт[]> = {

    статус: "успех",

    данные: [

    { id: "P001", название: "Ноутбук", цена: 75000 }

    ],

    метаданные: {

    timestamp: "2026-01-26T10:00:00Z",

    версия: "2.0"

    }

    };

    Readonly и Const

    Для неизменяемых данных:

    interface Конфигурация {
    

    readonly apiUrl: string;

    readonly timeout: number;

    readonly версия: string;

    }

    // Или использовать Readonly<T>

    type НеизменяемаяКонфигурация = Readonly<Конфигурация>;

    // Const assertions

    const конфиг = {

    apiUrl: "https://api.example.com",

    timeout: 5000,

    версия: "1.0.0"

    } as const;

    // Все свойства автоматически readonly

    Utility Types

    TypeScript предоставляет полезные утилиты:

    interface Пользователь {
    

    id: number;

    имя: string;

    email: string;

    пароль: string;

    возраст: number;

    }

    // Partial - все поля опциональные

    type ОбновлениеПользователя = Partial<Пользователь>;

    // Pick - выбрать определенные поля

    type ПубличныйПользователь = Pick<Пользователь, 'id' | 'имя' | 'email'>;

    // Omit - исключить поля

    type ПользовательБезПароля = Omit<Пользователь, 'пароль'>;

    // Required - все поля обязательные

    type ПолныйПользователь = Required<Partial<Пользователь>>;

    // Record

    type СписокПользователей = Record<number, Пользователь>;

    Валидация JSON данных

    Runtime валидация с Zod

    import { z } from 'zod';
    
    

    // Определение схемы

    const СхемаПользователя = z.object({

    id: z.number(),

    имя: z.string().min(1),

    email: z.string().email(),

    возраст: z.number().min(0).max(150),

    роли: z.array(z.string())

    });

    // Автоматическая генерация типа

    type Пользователь = z.infer<typeof СхемаПользователя>;

    // Парсинг и валидация

    function парситьПользователя(json: string): Пользователь {

    const данные = JSON.parse(json);

    return СхемаПользователя.parse(данные); // Бросит ошибку если невалидно

    }

    // Безопасный парсинг

    function безопасныйПарсинг(json: string) {

    try {

    const данные = JSON.parse(json);

    const результат = СхемаПользователя.safeParse(данные);

    if (результат.success) {

    return результат.data;

    } else {

    console.error('Ошибки валидации:', результат.error);

    return null;

    }

    } catch (error) {

    console.error('Ошибка парсинга JSON:', error);

    return null;

    }

    }

    io-ts

    import  as t from 'io-ts';
    
    

    // Определение кодека

    const ПользовательКодек = t.type({

    id: t.number,

    имя: t.string,

    email: t.string,

    активен: t.boolean,

    роли: t.array(t.string)

    });

    // Автоматический тип

    type Пользователь = t.TypeOf<typeof ПользовательКодек>;

    // Валидация

    import { isRight } from 'fp-ts/Either';

    function валидироватьПользователя(данные: unknown): Пользователь | null {

    const результат = ПользовательКодек.decode(данные);

    if (isRight(результат)) {

    return результат.right;

    } else {

    console.error('Ошибка валидации');

    return null;

    }

    }

    Работа с API ответами

    Типизация fetch запросов

    interface АпиОтвет<T> {
    

    статус: string;

    данные: T;

    метаданные?: {

    timestamp: string;

    };

    }

    interface Пользователь {

    id: number;

    имя: string;

    email: string;

    }

    async function получитьПользователя(id: number): Promise<Пользователь> {

    const ответ = await fetch(/api/users/${id});

    const json: АпиОтвет<Пользователь> = await ответ.json();

    return json.данные;

    }

    // Использование

    const пользователь = await получитьПользователя(123);

    console.log(пользователь.имя); // Типобезопасно!

    Generic fetch wrapper

    async function апиЗапрос<T>(url: string): Promise<T> {
    

    const ответ = await fetch(url);

    if (!ответ.ok) {

    throw new Error(HTTP ошибка! статус: ${ответ.status});

    }

    const данные: T = await ответ.json();

    return данные;

    }

    // Использование

    interface ПродуктОтвет {

    продукты: Array<{

    id: string;

    название: string;

    цена: number;

    }>;

    }

    const данные = await апиЗапрос<ПродуктОтвет>('/api/products');

    данные.продукты.forEach(продукт => {

    console.log(продукт.название); // Автодополнение работает!

    });

    JSON Schema к TypeScript

    Использование json-schema-to-typescript

    npm install -g json-schema-to-typescript

    JSON Schema:

    {
    

    "$schema": "http://json-schema.org/draft-07/schema#",

    "title": "Пользователь",

    "type": "object",

    "properties": {

    "id": {

    "type": "number"

    },

    "имя": {

    "type": "string",

    "minLength": 1

    },

    "email": {

    "type": "string",

    "format": "email"

    },

    "возраст": {

    "type": "number",

    "minimum": 0,

    "maximum": 150

    }

    },

    "required": ["id", "имя", "email"]

    }

    Генерация:

    json2ts schema.json > types.ts

    Результат:

    /
    

    Пользователь

    /

    export interface Пользователь {

    id: number;

    имя: string;

    email: string;

    возраст?: number;

    }

    Лучшие практики

    1. Используйте Interface vs Type appropriately

    // Interface для объектов (может быть расширен)
    

    interface Пользователь {

    имя: string;

    }

    interface Администратор extends Пользователь {

    права: string[];

    }

    // Type для union, intersection, primitives

    type ID = string | number;

    type Статус = "активен" | "неактивен" | "заблокирован";

    2. Именование типов

    // Хорошо - описательные имена
    

    interface ДанныеПользователя {

    // ...

    }

    interface АпиОтветПользователя {

    // ...

    }

    // Плохо - общие имена

    interface Data {

    // ...

    }

    interface Response {

    // ...

    }

    3. Разделение типов

    // types/user.ts
    

    export interface Пользователь {

    id: number;

    имя: string;

    }

    // types/product.ts

    export interface Продукт {

    id: string;

    название: string;

    }

    // types/index.ts

    export from './user';

    export from './product';

    4. Документирование типов

    /
    

    Представляет пользователя в системе

    /

    interface Пользователь {

    / Уникальный идентификатор пользователя /

    id: number;

    /* Полное имя пользователя /

    имя: string;

    /* Email адрес (должен быть уникальным) /

    email: string;

    /* Возраст пользователя (опционально) /

    возраст?: number;

    }

    5. Используйте строгие настройки TypeScript

    tsconfig.json:

    {
    

    "compilerOptions": {

    "strict": true,

    "noImplicitAny": true,

    "strictNullChecks": true,

    "strictFunctionTypes": true,

    "strictPropertyInitialization": true,

    "noImplicitThis": true,

    "alwaysStrict": true

    }

    }

    Заключение

    Конвертация JSON в TypeScript типы - важная часть разработки типобезопасных приложений. Современные инструменты делают этот процесс быстрым и простым.

    Ключевые выводы:

    • Используйте автоматическую генерацию для экономии времени
    • QuickType - лучший онлайн инструмент
    • Добавьте runtime валидацию с Zod или io-ts
    • Следуйте лучшим практикам именования и организации
    • Используйте строгие настройки TypeScript
    • Документируйте сложные типы

    Правильная типизация JSON данных повышает качество кода, уменьшает количество ошибок и улучшает опыт разработки!

    Share:

    Похожие статьи

    Read in English