15 промтов для генерации JavaScript и TypeScript кода: от React-компонентов до Node.js утилит

Введение

Генерация кода с помощью языковых моделей (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-разработчика.

Попробуйте эти промты в своей работе и адаптируйте под свои проекты. Удачи в кодинге!

← Все статьи

Комментарии

Читайте также

15 промтов для создания React/Next.js приложений: от компонентов до оптимизации

15 июля 2026

Освоение Vue.js и Nuxt в 2026 году: практическое руководство по реактивным интерфейсам, SSR и обучению с ИИ на asibiont.com

15 июля 2026

CISSP — сертифицированный специалист по информационной безопасности: освойте 8 доменов CBK с помощью AI-подготовки в 2026 году

15 июля 2026

Автоматизация SEO-мониторинга с интеграцией Google Search Console и AI-агентом ASI Biont

15 июля 2026

CRM и Salesforce — Управление взаимоотношениями с клиентами: конкурентное преимущество в карьере в 2026 году

15 июля 2026

Стратегический ход века: Stripe и Advent International готовят совместную покупку PayPal

15 июля 2026

От пользователя к создателю: как курс «Операционные системы и системное программирование» открывает ядро

15 июля 2026

Как новичку освоить Swift и iOS-разработку (SwiftUI) и опубликовать приложение в App Store за 4 месяца: разбор курса на asibiont.com

15 июля 2026

Ядерная энергетика и радиационная безопасность (МАГАТЭ, NRC): Как ИИ сокращает время обучения на 65% в области ядерного регулирования

15 июля 2026