Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Чтение и понимание требований функции - мой методический подход
Это важный навык. Перед написанием функции я всегда глубоко разбираюсь, что от неё требуется. Вот мой систематический процесс.
1. Анализ типов (TypeScript/JSDoc)
// TypeScript показывает ЧТО требует функция
function calculateDiscount(
price: number, // Необходимо число
discountPercent: number, // Процент скидки
minAmount?: number // Опциональный минимум
): number {
// Возвращает число (итоговую цену)
return price * (1 - discountPercent / 100);
}
// Если тип неправильный - TypeScript ругается:
calculateDiscount('100', 20); // ERROR: Argument of type 'string' is not assignable to parameter of type 'number'
calculateDiscount(100, 20); // OK
// JSDoc для документации функции
/**
* Вычисляет финальную цену с учётом скидки
* @param {number} price - Начальная цена в рублях
* @param {number} discountPercent - Процент скидки (0-100)
* @param {number} [minAmount=0] - Минимальная сумма для скидки
* @returns {number} Финальная цена
* @throws {Error} Если discountPercent < 0 или > 100
*/
function calculateDiscount(price, discountPercent, minAmount = 0) {
if (discountPercent < 0 || discountPercent > 100) {
throw new Error('Discount must be between 0 and 100');
}
if (price < minAmount) {
return price; // Скидка не применяется
}
return price * (1 - discountPercent / 100);
}
2. Анализ поведения (Unit тесты)
// Тесты показывают КАКОЕ поведение ожидается
describe('calculateDiscount', () => {
test('должна применить скидку корректно', () => {
expect(calculateDiscount(1000, 20)).toBe(800);
});
test('должна вернуть исходную цену если скидка 0%', () => {
expect(calculateDiscount(1000, 0)).toBe(1000);
});
test('должна работать с минимальной суммой', () => {
expect(calculateDiscount(500, 20, 1000)).toBe(500); // Скидка не применена
expect(calculateDiscount(1500, 20, 1000)).toBe(1200); // Скидка применена
});
test('должна выбросить ошибку при неправильных параметрах', () => {
expect(() => calculateDiscount(1000, 150)).toThrow();
});
});
// Читая тесты, я понимаю:
// - Какие edge cases нужно обработать
// - Какие значения считаются валидными
// - Какие исключительные ситуации возникают
3. Анализ сигнатуры функции
// Простая функция - простые требования
function sum(a: number, b: number): number {
return a + b;
}
// Сложная функция - сложные требования
interface FetchOptions {
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
headers?: Record<string, string>;
body?: unknown;
timeout?: number;
retries?: number;
}
interface ApiResponse<T> {
data: T;
status: number;
headers: Record<string, string>;
}
async function fetchWithRetry<T>(
url: string,
options?: FetchOptions
): Promise<ApiResponse<T>> {
// Требования из сигнатуры:
// 1. Принимает URL строку
// 2. Опциональный объект конфигурации
// 3. Generic тип T для типизации данных
// 4. Возвращает Promise с типизированным ответом
// 5. Может быть awaited (async function)
}
// Читаю сигнатуру и вижу требования:
// - Должна быть асинхронной
// - Должна работать с любым типом данных (generics)
// - Должна поддерживать множество опций
// - Должна возвращать структурированный ответ
4. Документация и комментарии
// Хорошая документация показывает требования явно
/**
* Форматирует дату в русский формат
* @example
* formatDate(new Date('2024-01-15')) // '15 января 2024'
* formatDate(new Date('2024-01-15'), 'short') // '15.01.2024'
*
* @param date - Дата для форматирования
* @param format - Формат ('long' | 'short'), по умолчанию 'long'
* @returns Отформатированная дата на русском языке
*/
function formatDate(date: Date, format: 'long' | 'short' = 'long'): string {
// ...
}
// Читая примеры в @example, я вижу ТОЧНОЕ поведение
// которое ожидается от функции
5. Анализ контекста использования
// Где функция используется - показывает требования
// В компоненте React:
export function UserProfile() {
const user = fetchUser(123); // Требует ID пользователя
// Значит функция должна:
// 1. Принимать number (ID)
// 2. Загружать асинхронно (используется в компоненте)
// 3. Возвращать user объект или null
}
// В form handler:
const handleSubmit = (data) => {
const errors = validateFormData(data);
if (errors.length === 0) {
submitForm(data);
}
};
// Требования из контекста:
// - validateFormData возвращает массив ошибок
// - пустой массив = валидные данные
// - submitForm принимает те же данные
6. Читаю код чтобы понять требования
// Если вижу функцию в эксплуатации, понимаю требования:
const apiClient = new ApiClient({
baseUrl: 'https://api.example.com',
timeout: 5000,
retryCount: 3
});
// Требования для конструктора:
// - Принимает объект конфигурации
// - baseUrl должен быть строкой
// - timeout число в миллисекундах
// - retryCount число попыток
const response = await apiClient.get('/users', {
params: { page: 1, limit: 10 },
headers: { 'X-Api-Key': 'secret' }
});
// Требования для .get:
// - Асинхронная функция
// - Первый параметр - endpoint
// - Второй - опции (params, headers)
// - Возвращает Promise с ответом
7. Вопросы которые я себе задаю
// Когда видю функцию, я спрашиваю:
// 1. Какие типы параметров нужны?
// - Принимает примитивы? Объекты? Arrays?
// 2. Какие параметры обязательные, какие опциональные?
// - Должны быть дефолтные значения?
// 3. Что функция возвращает?
// - Value, Promise, Observable, void?
// 4. Какие edge cases нужно обработать?
// - null/undefined? Пустые строки? Отрицательные числа?
// 5. Какие ошибки может вызвать?
// - throws ошибку или возвращает null?
// 6. Побочные эффекты (side effects)?
// - Изменяет глобальное состояние?
// - Делает API запросы?
// - Логирует что-то?
// Пример применения вопросов:
function updateUserProfile(userId: string, updates: Partial<User>) {
// 1. Типы: string, объект (Partial означает опциональные поля)
// 2. Обязательны оба параметра
// 3. Видимо возвращает Promise<User> (асинхронная)
// 4. Edge cases: пустой userId? Пустой updates object?
// 5. Может выбросить 404 если пользователь не найден
// 6. Side effects: делает PUT запрос, обновляет базу
}
8. Я всегда проверяю наличие типов
// TypeScript делает требования ЯВНЫМИ
interface Button {
text: string;
onClick: () => void; // Требует callback без параметров
disabled?: boolean; // Опциональное свойство
variant?: 'primary' | 'secondary'; // Только эти варианты
}
// VS неясный JavaScript:
function Button(props) {
// Что в props? Какие поля обязательны?
// Это гадание!
}
// Хороший JavaScript (с JSDoc):
/**
* @param {Object} props
* @param {string} props.text
* @param {Function} props.onClick
* @param {boolean} [props.disabled]
*/
function Button(props) {
// Теперь ясно
}
Итого: система понимания требований
- Сигнатура - первый источник информации (типы параметров и возврата)
- Документация - примеры и описание поведения
- Тесты - точное определение требуемого поведения
- Контекст использования - как функция применяется
- Исходный код - детали реализации
- Типы (TypeScript) - явное выражение требований
Чем полнее я вижу эту информацию, тем лучше я понимаю требования функции и могу её эффективно использовать или модифицировать.