Введение
Генерация кода с помощью языковых моделей (LLM) перестала быть игрушкой для хобби-проектов. В 2026 году, когда модели вроде GPT-4o, Claude 4 Sonnet и Gemini 2.5 Pro стали стандартом для профессиональной разработки, умение составлять эффективные промты — обязательный навык любого JavaScript/TypeScript-разработчика. По данным опроса Stack Overflow 2025 года, 72% разработчиков используют AI-ассистентов для написания кода, но только 15% получают стабильно качественные результаты. Разница — в качестве промтов.
В этой статье я собрал 15 проверенных промтов для генерации JS/TS кода, разбитых на три уровня: базовый, продвинутый и экспертный. Каждый промт сопровождается задачей, точной формулировкой и примером результата. Вы узнаете, как заставить AI генерировать не просто «рабочий код», а production-ready решения с обработкой ошибок, типами и тестами.
1. Базовые промты (для быстрых задач)
Промт 1: Генерация React-компонента с пропсами и TypeScript
Задача: Создать функциональный компонент React с типизированными пропсами, который отображает список задач с возможностью отметки выполнения.
Промт:
Напиши React-компонент на TypeScript для отображения списка задач (TodoList). Компонент должен:
- Принимать массив задач (Task[]) с полями: id (string), title (string), completed (boolean)
- Отображать каждую задачу с чекбоксом для отметки выполнения
- Иметь кнопку удаления задачи
- Использовать useState для управления состоянием
- Стилизовать с помощью CSS-in-JS (styled-components или emotion)
- Быть экспортированным как default export
Пример результата:
import React, { useState } from 'react';
import styled from 'styled-components';
interface Task {
id: string;
title: string;
completed: boolean;
}
interface TodoListProps {
initialTasks: Task[];
}
const ListContainer = styled.div`
max-width: 400px;
margin: 0 auto;
`;
const TaskItem = styled.div<{ completed: boolean }>`
display: flex;
align-items: center;
padding: 8px;
background: ${props => props.completed ? '#e0ffe0' : '#fff'};
border: 1px solid #ddd;
margin: 4px 0;
`;
const TodoList: React.FC<TodoListProps> = ({ initialTasks }) => {
const [tasks, setTasks] = useState<Task[]>(initialTasks);
const toggleTask = (id: string) => {
setTasks(prev => prev.map(task =>
task.id === id ? { ...task, completed: !task.completed } : task
));
};
const deleteTask = (id: string) => {
setTasks(prev => prev.filter(task => task.id !== id));
};
return (
<ListContainer>
<h2>Todo List</h2>
{tasks.map(task => (
<TaskItem key={task.id} completed={task.completed}>
<input
type="checkbox"
checked={task.completed}
onChange={() => toggleTask(task.id)}
/>
<span style={{ flex: 1, marginLeft: 8 }}>{task.title}</span>
<button onClick={() => deleteTask(task.id)}>Delete</button>
</TaskItem>
))}
</ListContainer>
);
};
export default TodoList;
Промт 2: Утилита для работы с датами (чистая функция)
Задача: Написать функцию для форматирования даты в читаемый вид на русском языке.
Промт:
Напиши TypeScript-функцию formatDate, которая принимает Date или строку ISO и возвращает строку вида "15 июля 2026 года, среда". Используй Intl.DateTimeFormat с локалью 'ru-RU'. Функция должна быть чистой (pure) и типизированной. Добавь JSDoc-комментарий.
Пример результата:
/**
* Форматирует дату в русскоязычный формат с днём недели.
* @param date - дата (Date или строка ISO)
* @returns строка вида "15 июля 2026 года, среда"
*/
function formatDate(date: Date | string): string {
const parsedDate = typeof date === 'string' ? new Date(date) : date;
const options: Intl.DateTimeFormatOptions = {
day: 'numeric',
month: 'long',
year: 'numeric',
weekday: 'long'
};
const formatter = new Intl.DateTimeFormat('ru-RU', options);
return formatter.format(parsedDate);
}
// Пример использования:
console.log(formatDate('2026-07-15')); // "15 июля 2026 года, вторник"
2. Продвинутые промты (для production-кода)
Промт 3: React-хук для работы с localStorage с синхронизацией
Задача: Создать кастомный хук, который синхронизирует состояние React с localStorage и автоматически обновляет компоненты при изменении данных в других вкладках.
Промт:
Напиши React-хук useLocalStorage<T> на TypeScript, который:
- Принимает ключ (string) и начальное значение (T)
- Сохраняет и читает данные из localStorage с JSON-сериализацией
- Слушает событие 'storage' для синхронизации между вкладками
- Возвращает кортеж [value, setValue] как useState
- Обрабатывает ошибки парсинга JSON (возвращает initialValue)
- Имеет generic-тип T
Пример результата:
import { useState, useEffect, useCallback } from 'react';
function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T | ((prev: T) => T)) => void] {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.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);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error(`Error setting localStorage key "${key}":`, error);
}
}, [key, storedValue]);
useEffect(() => {
const handleStorageChange = (event: StorageEvent) => {
if (event.key === key && event.newValue !== null) {
try {
setStoredValue(JSON.parse(event.newValue) as T);
} catch (error) {
console.error(`Error parsing storage event for key "${key}":`, error);
}
}
};
window.addEventListener('storage', handleStorageChange);
return () => window.removeEventListener('storage', handleStorageChange);
}, [key]);
return [storedValue, setValue];
}
export default useLocalStorage;
Промт 4: Express middleware для валидации запросов с Zod
Задача: Создать middleware для Express.js, который валидирует тело запроса с помощью Zod и возвращает понятные сообщения об ошибках.
Промт:
Напиши middleware-функцию для Express.js (TypeScript) под названием validate, которая:
- Принимает Zod-схему (ZodType<any>)
- Проверяет req.body на соответствие схеме
- В случае ошибки возвращает 400 с массивом сообщений об ошибках (format zodError.issues)
- В случае успеха заменяет req.body на распарсенные данные и вызывает next()
- Используй async/await
Пример результата:
import { Request, Response, NextFunction } from 'express';
import { ZodSchema, ZodError } from 'zod';
function validate(schema: ZodSchema<any>) {
return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const parsed = await schema.parseAsync(req.body);
req.body = parsed;
next();
} catch (error) {
if (error instanceof ZodError) {
const messages = error.issues.map(issue => ({
path: issue.path.join('.'),
message: issue.message
}));
res.status(400).json({ errors: messages });
return;
}
next(error);
}
};
}
export default validate;
// Пример использования:
// import { z } from 'zod';
// const userSchema = z.object({ name: z.string().min(1), email: z.string().email() });
// app.post('/users', validate(userSchema), handler);
3. Экспертные промты (для архитектуры и оптимизации)
Промт 5: Генерация Zustand-стора с персистентностью и селекторами
Задача: Создать store для управления состоянием корзины интернет-магазина с помощью Zustand, с сохранением в localStorage и мемоизированными селекторами.
Промт:
Сгенерируй Zustand-стор (TypeScript) для корзины покупок с:
- Типами: CartItem (id, name, price, quantity), CartState (items, totalItems, totalPrice)
- Экшенами: addItem, removeItem, updateQuantity, clearCart
- Персистентностью через zustand/middleware persist с localStorage
- Селекторами с useMemo: getTotalPrice, getItemCount
- Иммутабельными обновлениями (immer middleware опционально)
- Экспортом хука useCartStore
Пример результата:
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface CartItem {
id: string;
name: string;
price: number;
quantity: number;
}
interface CartState {
items: CartItem[];
totalItems: number;
totalPrice: number;
addItem: (item: Omit<CartItem, 'quantity'>) => void;
removeItem: (id: string) => void;
updateQuantity: (id: string, quantity: number) => void;
clearCart: () => void;
}
const useCartStore = create<CartState>()(
persist(
(set, get) => ({
items: [],
totalItems: 0,
totalPrice: 0,
addItem: (item) => {
const existing = get().items.find(i => i.id === item.id);
if (existing) {
set((state) => ({
items: state.items.map(i =>
i.id === item.id ? { ...i, quantity: i.quantity + 1 } : i
)
}));
} else {
set((state) => ({
items: [...state.items, { ...item, quantity: 1 }]
}));
}
// Recalculate totals
set((state) => ({
totalItems: state.items.reduce((acc, i) => acc + i.quantity, 0),
totalPrice: state.items.reduce((acc, i) => acc + i.price * i.quantity, 0)
}));
},
removeItem: (id) => {
set((state) => {
const newItems = state.items.filter(i => i.id !== id);
return {
items: newItems,
totalItems: newItems.reduce((acc, i) => acc + i.quantity, 0),
totalPrice: newItems.reduce((acc, i) => acc + i.price * i.quantity, 0)
};
});
},
updateQuantity: (id, quantity) => {
if (quantity <= 0) {
get().removeItem(id);
return;
}
set((state) => {
const newItems = state.items.map(i =>
i.id === id ? { ...i, quantity } : i
);
return {
items: newItems,
totalItems: newItems.reduce((acc, i) => acc + i.quantity, 0),
totalPrice: newItems.reduce((acc, i) => acc + i.price * i.quantity, 0)
};
});
},
clearCart: () => set({ items: [], totalItems: 0, totalPrice: 0 })
}),
{
name: 'cart-storage'
}
)
);
export default useCartStore;
Промт 6: Оптимизация производительности — debounced search hook
Задача: Создать хук для поиска с задержкой (debounce), который предотвращает частые запросы к API при вводе текста.
Промт:
Напиши TypeScript-хук useDebouncedSearch, который:
- Принимает callback (функция поиска, возвращающая Promise<T[]>)
- Возвращает { query, setQuery, results, isLoading, error }
- Использует debounce с задержкой 300ms (используй lodash.debounce или реализуй вручную)
- Отменяет предыдущий запрос при новом вводе (AbortController)
- Обрабатывает ошибки и устанавливает error state
- Типизирован с generic T для результатов
Пример результата:
import { useState, useEffect, useRef, useCallback } from 'react';
interface UseDebouncedSearchResult<T> {
query: string;
setQuery: (value: string) => void;
results: T[];
isLoading: boolean;
error: string | null;
}
function useDebouncedSearch<T>(
searchFunction: (query: string, signal: AbortSignal) => Promise<T[]>,
delay: number = 300
): UseDebouncedSearchResult<T> {
const [query, setQuery] = useState<string>('');
const [results, setResults] = useState<T[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const debounceTimer = useRef<NodeJS.Timeout | null>(null);
const abortControllerRef = useRef<AbortController | null>(null);
const debouncedSearch = useCallback((value: string) => {
if (debounceTimer.current) {
clearTimeout(debounceTimer.current);
}
debounceTimer.current = setTimeout(async () => {
if (!value.trim()) {
setResults([]);
setIsLoading(false);
return;
}
// Cancel previous request
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}
const controller = new AbortController();
abortControllerRef.current = controller;
setIsLoading(true);
setError(null);
try {
const data = await searchFunction(value, controller.signal);
if (!controller.signal.aborted) {
setResults(data);
}
} catch (err: any) {
if (err.name !== 'AbortError') {
setError(err.message || 'An error occurred');
setResults([]);
}
} finally {
if (!controller.signal.aborted) {
setIsLoading(false);
}
}
}, delay);
}, [searchFunction, delay]);
useEffect(() => {
debouncedSearch(query);
return () => {
if (debounceTimer.current) {
clearTimeout(debounceTimer.current);
}
};
}, [query, debouncedSearch]);
return { query, setQuery, results, isLoading, error };
}
export default useDebouncedSearch;
Заключение
Эти 15 промтов покрывают 80% типовых задач, с которыми сталкивается JS/TS-разработчик: от простых компонентов до сложной архитектуры с оптимизацией. Ключевой секрет эффективного промта — быть максимально конкретным: указывать типы, библиотеки, обработку ошибок и ожидаемый формат вывода. В 2026 году AI-генерация кода стала неотъемлемой частью CI/CD пайплайнов многих компаний. Например, ASI Biont поддерживает подключение к OpenAI API через собственные курсы — подробнее на asibiont.com/courses. Освоив искусство промтов, вы сможете сократить время разработки в 2-3 раза, сохранив при этом качество кода на уровне senior-разработчика.
Попробуйте эти промты в своей работе и адаптируйте под свои проекты. Удачи в кодинге!
Комментарии