TypeScript стал стандартом де-факто для веб-разработки, но строгая типизация и миграции с JavaScript по-прежнему отнимают много времени. Особенно в командах, где нет выделенного senior-разработчика, который мог бы проверить каждый PR и объяснить, почему any — это плохо. В 2026 году LLM научились генерировать не просто рабочий код, а типобезопасный код, если правильно сформулировать запрос.
В этой подборке — 12 промтов, которые превращают ChatGPT, Claude или любую другую модель в вашего TypeScript-напарника. Каждый промт решает конкретную боль: от генерации строгих типов до автоматического ревью пул-реквестов. Мы проверили их на реальных проектах — вот что работает.
Базовые промты: фундамент типобезопасности
1. Генерация интерфейсов из JSON
Задача: быстро получить TypeScript-типы из ответа API, не описывая их вручную.
Промт:
Ты — эксперт по TypeScript. Преобразуй следующий JSON в набор интерфейсов. Используй строгие типы, избегай any. Если поле может быть null или undefined, отрази это. Вложенные объекты вынеси в отдельные интерфейсы.
JSON:
{
"user": {
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"address": {
"street": "123 Main St",
"city": "Wonderland"
},
"tags": ["admin", "user"]
}
}
Результат:
interface Address {
street: string;
city: string;
}
interface User {
id: number;
name: string;
email: string;
address: Address;
tags: string[];
}
Модель создаст аккуратные интерфейсы без лишних вложенностей. Если в JSON есть неоднородные массивы, она предложит union-типы.
zod или io-ts. Модель может ошибиться в опциональности полей.
2. Строгая типизация функций
Задача: добавить аннотации типов в существующую функцию, написанную на JS.
Промт:
Добавь строгие типы TypeScript к следующей функции. Укажи типы параметров и возвращаемого значения. Если функция может вернуть null или undefined, используй union-тип. Не используй any.
function calculateTotal(items, discount) {
let total = 0;
for (let item of items) {
total += item.price * item.quantity;
}
if (discount) {
total *= (1 - discount);
}
return total;
}
Результат:
interface CartItem {
price: number;
quantity: number;
}
function calculateTotal(items: CartItem[], discount?: number): number {
let total = 0;
for (const item of items) {
total += item.price * item.quantity;
}
if (discount) {
total *= (1 - discount);
}
return total;
}
Модель не только расставит типы, но и создаст вспомогательный интерфейс для элементов массива.
3. Конвертация JS-файла в TS
Задача: перевести целый файл с JavaScript на TypeScript с минимальными изменениями.
Промт:
Преобразуй следующий JavaScript-код в TypeScript. Добавь необходимые импорты, интерфейсы и аннотации типов. Сохрани логику без изменений. Если используются внешние библиотеки, добавь соответствующие типы (например, из @types).
// JavaScript код
const express = require('express');
const app = express();
app.get('/user/:id', (req, res) => {
const userId = parseInt(req.params.id, 10);
res.json({ id: userId, name: 'User' + userId });
});
app.listen(3000);
Результат:
import express, { Request, Response } from 'express';
const app = express();
app.get('/user/:id', (req: Request, res: Response) => {
const userId = parseInt(req.params.id, 10);
res.json({ id: userId, name: `User${userId}` });
});
app.listen(3000);
Модель заменит require на import, добавит типы для req и res.
Продвинутые промты: дженерики, утилиты и миграции
4. Создание дженерик-функции
Задача: написать типобезопасную функцию, работающую с разными типами.
Промт:
Напиши дженерик-функцию `pluck`, которая принимает массив объектов и имя свойства, а возвращает массив значений этого свойства. Обеспечь типобезопасность: свойство должно существовать в типе элемента массива. Используй keyof и extends.
Результат:
function pluck<T, K extends keyof T>(items: T[], key: K): T[K][] {
return items.map(item => item[key]);
}
// Пример использования
interface Person {
name: string;
age: number;
}
const people: Person[] = [{ name: 'Alice', age: 30 }];
const names = pluck(people, 'name'); // string[]
Такая функция не скомпилируется, если передать несуществующее свойство.
5. Миграция с PropTypes на TypeScript
Задача: заменить React PropTypes на TS-интерфейсы.
Промт:
Преобразуй React-компонент с PropTypes в TypeScript-компонент с интерфейсом пропсов. Убедись, что все пропсы типизированы, а PropTypes удалены. Используй React.FC или обычную функцию — на твой выбор.
import React from 'react';
import PropTypes from 'prop-types';
function Greeting({ name, age }) {
return <div>Hello, {name}! You are {age} years old.</div>;
}
Greeting.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number
};
Результат:
import React from 'react';
interface GreetingProps {
name: string;
age?: number;
}
const Greeting: React.FC<GreetingProps> = ({ name, age }) => {
return <div>Hello, {name}! You are {age} years old.</div>;
};
Модель корректно определит опциональность age (не помечен isRequired).
6. Генерация утилитных типов
Задача: создать сложный утилитный тип для проекта.
Промт:
Напиши утилитный тип `DeepPartial<T>`, который делает все свойства объекта опциональными рекурсивно, включая вложенные объекты и массивы. Не используй any.
Результат:
type DeepPartial<T> = T extends object
? { [P in keyof T]?: DeepPartial<T[P]> }
: T;
Этот тип часто нужен для функций обновления состояния.
7. Миграция с Flow на TypeScript
Задача: перевести проект с Flow на TS.
Промт:
Преобразуй следующий Flow-код в TypeScript. Замени `type` на `interface` или `type` в зависимости от ситуации, убери `?` для опциональных полей, используй `?` для опциональных параметров функций.
type User = {
id: number,
name: string,
age?: number
};
function greet(user: User): string {
return `Hello, ${user.name}`;
}
Результат:
interface User {
id: number;
name: string;
age?: number;
}
function greet(user: User): string {
return `Hello, ${user.name}`;
}
Синтаксис почти идентичен, но модель обратит внимание на различия.
Экспертные промты: ревью, тесты и сложные случаи
8. Ревью PR на TypeScript
Задача: автоматически проверить пул-реквест на типизацию и потенциальные ошибки.
Промт:
Ты — senior TypeScript-разработчик. Проведи ревью следующего кода. Найди:
- неявные any
- отсутствующие типы возврата
- потенциальные ошибки с null/undefined
- нарушения принципов типобезопасности
Предложи исправления.
function getUser(id) {
return fetch(`/api/users/${id}`).then(res => res.json());
}
Результат:
Модель укажет, что параметр id не типизирован, возвращаемый тип — Promise<any>, и предложит:
interface User {
id: number;
name: string;
}
async function getUser(id: number): Promise<User> {
const res = await fetch(`/api/users/${id}`);
return res.json() as Promise<User>;
}
9. Генерация тестов с типами
Задача: написать юнит-тесты для типизированной функции.
Промт:
Напиши тесты на Jest для функции `pluck`. Убедись, что тесты проверяют типы (используй ts-jest). Включи тест на несуществующее свойство (должен быть ошибкой компиляции).
Результат:
import { pluck } from './pluck';
describe('pluck', () => {
it('should return values of a property', () => {
const items = [{ name: 'Alice' }, { name: 'Bob' }];
expect(pluck(items, 'name')).toEqual(['Alice', 'Bob']);
});
it('should not compile with invalid property', () => {
const items = [{ name: 'Alice' }];
// @ts-expect-error
pluck(items, 'age');
});
});
Модель добавит @ts-expect-error для проверки ошибки компиляции.
10. Создание type guard
Задача: написать функцию-предикат для сужения типа.
Промт:
Создай type guard `isUser`, которая проверяет, что объект соответствует интерфейсу User. Используй проверку всех полей и их типов.
Результат:
interface User {
id: number;
name: string;
}
function isUser(obj: any): obj is User {
return (
typeof obj === 'object' &&
obj !== null &&
typeof obj.id === 'number' &&
typeof obj.name === 'string'
);
}
11. Работа с discriminated unions
Задача: сгенерировать тип для состояний с дискриминантом.
Промт:
Опиши discriminated union для состояний загрузки данных: idle, loading, success (с данными), error (с сообщением). Используй поле `status` как дискриминант.
Результат:
type LoadingState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: T }
| { status: 'error'; message: string };
12. Оптимизация типов для производительности
Задача: упростить сложные типы, чтобы ускорить компиляцию.
Промт:
Проанализируй этот тип и предложи упрощение для улучшения производительности компилятора. Используй mapped types и conditional types эффективно.
type ComplexType<T> = {
[K in keyof T]: T[K] extends object ? ComplexType<T[K]> : T[K]
};
Результат:
Модель может предложить использовать DeepReadonly или разбить на более простые типы.
--diagnostics. LLM может предложить неоптимальное решение.
Как внедрить промты в рабочий процесс
Начните с базовых промтов для генерации типов — они дают быстрый выигрыш. Затем добавьте ревью PR в CI с помощью GitHub Actions и вызова LLM API. Например, можно настроить бота, который комментирует PR с замечаниями по типизации.
Помните: LLM не заменяет senior-разработчика, но может стать мощным ассистентом, который берёт на себя рутину. Главное — проверять сгенерированный код и использовать строгие настройки TypeScript (strict: true).
Попробуйте эти промты в своём следующем проекте — и вы удивитесь, насколько быстрее пойдёт работа с типами.
Комментарии