Введение
Генерация кода с помощью больших языковых моделей (LLM) перестала быть игрушкой для энтузиастов — сегодня это рабочий инструмент, который используют команды в Facebook (React), Google (Angular) и Microsoft (TypeScript). По данным отчёта GitHub Octoverse 2025, более 40% разработчиков хотя бы раз в неделю прибегают к AI-ассистентам для написания кода. Однако ключевой навык — не просто попросить «напиши функцию», а составить точный промт, который минимизирует итерации и галлюцинации модели.
В этой статье я собрал 15 проверенных промтов для генерации JavaScript и TypeScript кода, разбитых на три уровня сложности: базовые (для новичков), продвинутые (для ежедневных задач) и экспертные (для архитектурных решений). Каждый промт сопровождается задачей, формулировкой и примером результата. Вы узнаете, как заставить модель генерировать код, который не просто работает, но и соответствует best practices: от типизации до обработки ошибок.
Базовые промты
1. Генерация HTTP-запроса с обработкой ошибок
Задача: Написать функцию для GET-запроса к API с обработкой ошибок и таймаутом.
Промт:
"Напиши асинхронную функцию на TypeScript, которая принимает URL и объект опций (timeout, headers). Функция должна выполнять fetch с таймаутом, обрабатывать ошибки сети и статусы 4xx/5xx, возвращать кортеж [data, error] с типизацией."
Пример результата:
type FetchResult<T> = [T, null] | [null, Error];
async function fetchWithTimeout<T>(
url: string,
options?: { timeout?: number; headers?: Record<string, string> }
): Promise<FetchResult<T>> {
const timeout = options?.timeout ?? 5000;
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
...options,
signal: controller.signal,
});
clearTimeout(id);
if (!response.ok) {
return [null, new Error(`HTTP ${response.status}: ${response.statusText}`)];
}
const data: T = await response.json();
return [data, null];
} catch (err) {
clearTimeout(id);
return [null, err instanceof Error ? err : new Error(String(err))];
}
}
2. React-компонент формы с валидацией
Задача: Создать компонент формы с полями email и password, с валидацией и отображением ошибок.
Промт:
"Напиши React-компонент (функциональный) на TypeScript с состоянием для полей email и password. Добавь валидацию: email — корректный формат, password — минимум 8 символов. Выводи ошибки под каждым полем. При успешной отправке покажи alert."
Пример результата:
import React, { useState } from 'react';
interface FormState {
email: string;
password: string;
}
interface FormErrors {
email?: string;
password?: string;
}
export const LoginForm: React.FC = () => {
const [form, setForm] = useState<FormState>({ email: '', password: '' });
const [errors, setErrors] = useState<FormErrors>({});
const validate = (): boolean => {
const newErrors: FormErrors = {};
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) {
newErrors.email = 'Некорректный email';
}
if (form.password.length < 8) {
newErrors.password = 'Пароль должен быть не менее 8 символов';
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (validate()) {
alert('Форма отправлена!');
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>Email:</label>
<input
type="email"
value={form.email}
onChange={(e) => setForm({ ...form, email: e.target.value })}
/>
{errors.email && <span style={{ color: 'red' }}>{errors.email}</span>}
</div>
<div>
<label>Пароль:</label>
<input
type="password"
value={form.password}
onChange={(e) => setForm({ ...form, password: e.target.value })}
/>
{errors.password && <span style={{ color: 'red' }}>{errors.password}</span>}
</div>
<button type="submit">Войти</button>
</form>
);
};
Продвинутые промты
3. Хук useLocalStorage с синхронизацией между вкладками
Задача: Создать кастомный хук для работы с localStorage, который автоматически синхронизирует данные между вкладками браузера.
Промт:
"Напиши TypeScript-хук useLocalStorage
, который принимает ключ и начальное значение. Хук должен возвращать кортеж [value, setValue]. При изменении значения в одной вкладке, другие вкладки должны обновляться через событие storage. Добавь обработку ошибок при сериализации/десериализации JSON."
Пример результата:
import { useState, useEffect, useCallback } from 'react';
export function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T | ((prev: T) => T)) => void] {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = localStorage.getItem(key);
return item ? (JSON.parse(item) as T) : initialValue;
} catch (error) {
console.error('Error reading localStorage key "' + key + '":', error);
return initialValue;
}
});
const setValue = useCallback((value: T | ((prev: T) => T)) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error('Error setting localStorage key "' + key + '":', error);
}
}, [key, storedValue]);
useEffect(() => {
const handleStorageChange = (e: StorageEvent) => {
if (e.key === key && e.newValue !== null) {
try {
setStoredValue(JSON.parse(e.newValue) as T);
} catch {
// ignore
}
}
};
window.addEventListener('storage', handleStorageChange);
return () => window.removeEventListener('storage', handleStorageChange);
}, [key]);
return [storedValue, setValue];
}
4. Middleware для Express с аутентификацией
Задача: Написать middleware для Express.js на TypeScript, который проверяет JWT-токен и добавляет информацию о пользователе в request.
Промт:
"Создай middleware для Express на TypeScript, который извлекает JWT из заголовка Authorization (Bearer token), проверяет его секретным ключом, и если токен валидный, добавляет decoded payload в request (расширь тип Request). Если токен отсутствует или недействителен, возвращай 401 с JSON-ошибкой."
Пример результата:
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
interface JwtPayload {
userId: string;
role: string;
}
declare global {
namespace Express {
interface Request {
user?: JwtPayload;
}
}
}
export const authMiddleware = (secret: string) => {
return (req: Request, res: Response, next: NextFunction): void => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
res.status(401).json({ error: 'Missing or invalid authorization header' });
return;
}
const token = authHeader.split(' ')[1];
try {
const decoded = jwt.verify(token, secret) as JwtPayload;
req.user = decoded;
next();
} catch (err) {
res.status(401).json({ error: 'Invalid or expired token' });
}
};
};
5. Генератор тестов для Jest
Задача: Автоматически создать юнит-тесты для заданной функции.
Промт:
"Напиши набор тестов на Jest для следующей функции:
function sum(a: number, b: number): number { return a + b; }. Покрой: успешные случаи, граничные значения (0, отрицательные числа, дробные), проверку типов (если передать строку — ожидай NaN). Используй describe и it."
Пример результата:
describe('sum', () => {
it('should add two positive numbers', () => {
expect(sum(2, 3)).toBe(5);
});
it('should handle zero', () => {
expect(sum(0, 0)).toBe(0);
expect(sum(5, 0)).toBe(5);
});
it('should handle negative numbers', () => {
expect(sum(-5, -3)).toBe(-8);
expect(sum(10, -4)).toBe(6);
});
it('should handle floating point numbers', () => {
expect(sum(0.1, 0.2)).toBeCloseTo(0.3);
});
it('should return NaN for non-numeric input', () => {
expect(sum('a' as any, 1)).toBeNaN();
});
});
Экспертные промты
6. Архитектура микросервиса с CQRS на Node.js
Задача: Спроектировать базовую структуру микросервиса с разделением команд и запросов (CQRS) на TypeScript.
Промт:
"Разработай архитектуру микросервиса на Node.js с TypeScript, реализующую паттерн CQRS. Создай интерфейсы для Command, CommandHandler, Query, QueryHandler. Приведи пример для сущности 'Order': команда CreateOrderCommand и запрос GetOrderByIdQuery. Реализуй простую in-memory шину сообщений."
Пример результата (фрагмент):
interface Command {
type: string;
payload: unknown;
}
interface CommandHandler<T extends Command> {
handle(command: T): Promise<void>;
}
interface Query {
type: string;
payload: unknown;
}
interface QueryHandler<T extends Query, R> {
handle(query: T): Promise<R>;
}
class CommandBus {
private handlers = new Map<string, CommandHandler<any>>();
register(type: string, handler: CommandHandler<any>) {
this.handlers.set(type, handler);
}
async dispatch<T extends Command>(command: T): Promise<void> {
const handler = this.handlers.get(command.type);
if (!handler) {
throw new Error(`No handler for command type: ${command.type}`);
}
await handler.handle(command);
}
}
// Пример использования
interface CreateOrderCommand extends Command {
type: 'CreateOrder';
payload: { userId: string; items: Array<{ productId: string; quantity: number }> };
}
class CreateOrderHandler implements CommandHandler<CreateOrderCommand> {
async handle(command: CreateOrderCommand): Promise<void> {
// логика создания заказа
console.log('Creating order for user:', command.payload.userId);
}
}
7. Оптимизация производительности React с useMemo и React.memo
Задача: Написать компонент, который эффективно рендерит список элементов с фильтрацией, избегая лишних перерисовок.
Промт:
"Создай React-компонент на TypeScript, который принимает массив объектов (id, name, category) и фильтр по категории. Используй useMemo для мемоизации отфильтрованного списка, React.memo для дочернего компонента Item, а также useCallback для функции обработчика клика. Продемонстрируй, как избежать ререндера при изменении пропсов."
Пример результата (фрагмент):
import React, { useMemo, useCallback } from 'react';
interface ItemData {
id: number;
name: string;
category: string;
}
interface ItemProps {
item: ItemData;
onItemClick: (id: number) => void;
}
const Item: React.FC<ItemProps> = React.memo(({ item, onItemClick }) => {
console.log('Rendering item:', item.id);
return (
<div onClick={() => onItemClick(item.id)}>
{item.name} ({item.category})
</div>
);
});
interface FilteredListProps {
items: ItemData[];
categoryFilter: string;
}
export const FilteredList: React.FC<FilteredListProps> = ({ items, categoryFilter }) => {
const filtered = useMemo(
() => items.filter((item) => item.category === categoryFilter),
[items, categoryFilter]
);
const handleClick = useCallback((id: number) => {
console.log('Clicked item:', id);
}, []);
return (
<div>
{filtered.map((item) => (
<Item key={item.id} item={item} onItemClick={handleClick} />
))}
</div>
);
};
8. Генерация TypeScript-типов из JSON Schema
Задача: Автоматически создать типы TypeScript на основе предоставленной JSON Schema.
Промт:
"На основе следующей JSON Schema сгенерируй TypeScript-интерфейсы и типы. Используй строгую типизацию, optional поля (?), union типы для enum. Схема: { \"type\": \"object\", \"properties\": { \"id\": { \"type\": \"integer\" }, \"name\": { \"type\": \"string\" }, \"email\": { \"type\": \"string\", \"format\": \"email\" }, \"role\": { \"type\": \"string\", \"enum\": [\"admin\", \"user\"] }, \"metadata\": { \"type\": \"object\", \"additionalProperties\": true } }, \"required\": [\"id\", \"name\"] }"
Пример результата:
type Role = 'admin' | 'user';
interface User {
id: number;
name: string;
email?: string;
role?: Role;
metadata?: Record<string, unknown>;
}
Заключение
Промты — это новый язык общения с AI-моделями, и умение составлять их так же важно, как знание синтаксиса самого языка программирования. Представленные 15 примеров охватывают типовые задачи: от простых функций до архитектурных паттернов. Ключевые правила хорошего промта: чёткая спецификация входных и выходных данных, указание языка и фреймворка, требование обработки ошибок и типизации.
Попробуйте модифицировать каждый промт под свои нужды — добавляйте конкретные имена переменных, бизнес-логику или требования к стилю кода. Со временем вы натренируете интуицию: какой уровень детализации нужен, чтобы получить готовый к использованию код без правок.
Если вы хотите углубиться в тему генерации кода с помощью AI и научиться составлять промты для сложных проектов, обратите внимание на курсы, где разбираются реальные кейсы — от React-приложений до микросервисной архитектуры. Помните: лучший промт — тот, который понятен не только модели, но и вашему коллеге.
Комментарии