← Назад к вопросам

Для чего использовать void?

2.3 Middle🔥 121 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Для чего использовать void в TypeScript?

void - это специальный тип в TypeScript, который означает "функция ничего не возвращает". Это один из самых полезных типов для типизации и предотвращения ошибок.

Основное использование: функции без возврата

Пример 1: Функция с побочными эффектами

// Функция не возвращает значение, только выполняет действие
function printMessage(message: string): void {
  console.log(message);
  // return; // Можно, но не обязательно
}

printMessage("Hello"); // OK

const result = printMessage("Test"); // result = undefined
console.log(result); // undefined

Компилятор убедится, что вы не пытаетесь вернуть значение:

// Ошибка TypeScript!
function printMessage(message: string): void {
  return "Hello"; // Error: Type 'string' is not assignable to type 'void'
}

Практические примеры

Обработчики событий

// React компонент
interface ButtonProps {
  onClick: () => void; // Обработчик не должен возвращать значение
}

const MyButton: React.FC<ButtonProps> = ({ onClick }) => (
  <button onClick={onClick}>Click me</button>
);

// Использование
<MyButton onClick={() => {
  console.log("Clicked!");
  // return что-то - будет игнорировано
}} />

Обновление состояния

interface UserState {
  users: User[];
  loading: boolean;
}

// Функция обновляет состояние, ничего не возвращает
function clearUsers(state: UserState): void {
  state.users = [];
  state.loading = false;
}

Работа с массивами

// Array.forEach ожидает функцию void
const numbers = [1, 2, 3, 4, 5];

numbers.forEach((num: number): void => {
  console.log(num * 2); // Это OK
});

// Но вот это будет ошибкой!
// numbers.forEach((num: number): number => { // Error!
//   return num * 2;
// });

void vs undefined

Различие в смысле

// undefined - это тип значения
function getValue(): undefined {
  return undefined; // Явно возвращаем undefined
}

// void - это "ничего не возвращай"
function doSomething(): void {
  console.log("Something");
  // return; - необязательно
}

const a = getValue(); // a имеет тип undefined
const b = doSomething(); // b имеет тип undefined (переменная), но функция типа void

На практике они эквивалентны

const func1 = (): void => {};
const func2 = (): undefined => {};

// Обе функции возвращают undefined, но void понятнее
const result1 = func1(); // undefined
const result2 = func2(); // undefined

Полезное: void как тип параметра

Редко, но можно использовать void как тип параметра функции (хотя это плохая практика):

// Не рекомендуется, но валидно
function processCallback(callback: (x: number) => void): void {
  callback(42);
}

processCallback((num) => {
  console.log(num);
  // return что-то - будет игнорировано
});

Асинхронные функции и void

Для асинхронных функций void означает, что функция не возвращает полезный результат:

// Асинхронная функция не возвращает результат
async function fetchAndLog(url: string): Promise<void> {
  try {
    const response = await fetch(url);
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
  // Ничего не возвращаем
}

await fetchAndLog("https://api.example.com/data"); // OK

React Hooks и void

useEffect с void

// useEffect callback должна быть void или возвращать cleanup функцию
function MyComponent() {
  useEffect((): void => {
    console.log("Component mounted");
    
    // НО! Если нужна cleanup функция, то return нужен
    return () => {
      console.log("Component unmounted");
    };
  }, []);
}

// Это тоже OK
useEffect((): void => {
  console.log("Side effect");
  // Никаких return
}, []);

Когда использовать void

1. Функции, которые изменяют состояние

class Counter {
  private count = 0;
  
  increment(): void { // Изменяет состояние, не возвращает
    this.count++;
  }
  
  getCount(): number { // Возвращает значение
    return this.count;
  }
}

2. Обработчики событий

// DOM события
document.addEventListener('click', (e: MouseEvent): void => {
  console.log('Clicked at', e.clientX, e.clientY);
});

// React
const handleClick = (): void => {
  setOpen(!open);
};

3. Функции логирования и уведомлений

function logError(error: Error): void {
  console.error(error);
  sendToSentry(error); // Побочный эффект
}

function showToast(message: string): void {
  toast.show(message);
}

Типичная ошибка: забыть типизировать

// Плохо - нет типа возврата
function updateUser(id: number, data: UserData) {
  // Может ли эта функция что-то вернуть?
  // Непонятно!
  database.update(id, data);
}

// Хорошо - явно указан возврат
function updateUser(id: number, data: UserData): void {
  database.update(id, data);
}

Опасность: Function vs void

// Это РАЗНЫЕ типы!
type FunctionType = () => void;      // Функция, которая ничего не возвращает
type UndefinedType = () => undefined; // Функция, которая возвращает undefined

const f1: FunctionType = () => {
  console.log("OK");
};

const f2: FunctionType = () => {
  return 42; // Error! Type 'number' is not assignable to type 'void'
};

// Но:
const f3: FunctionType = () => "string"; // Ошибка!

Strict mode и void

В строгом режиме TypeScript (strict: true) void очень важен:

// tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitReturns": true,
    "noImplicitAny": true
  }
}
// С strict: true это ошибка
function processData(data: any) { // Error: no return type!
  console.log(data);
}

// Правильно
function processData(data: any): void {
  console.log(data);
}

Checklist: Когда использовать void

СитуацияТип
Функция изменяет состояниеvoid
Обработчик событияvoid
Логирование/уведомлениеvoid
Функция возвращает значениеnumber/string/object
Promise без результатаPromise<void>
useEffect без cleanupvoid или () => void

Практический пример: Полная типизация

// Компонент с правильной типизацией
interface FormProps {
  onSubmit: (data: FormData) => void; // Обработчик ничего не возвращает
  onCancel: () => void; // Обработчик отмены
}

const Form: React.FC<FormProps> = ({ onSubmit, onCancel }) => {
  const [formData, setFormData] = useState<FormData>({});
  
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };
  
  const handleSubmit = (e: React.FormEvent): void => {
    e.preventDefault();
    onSubmit(formData); // Вызываем callback
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input onChange={handleChange} />
      <button type="submit">Submit</button>
      <button type="button" onClick={onCancel}>Cancel</button>
    </form>
  );
};

Вывод

void используется для типизации функций, которые:

  • Ничего не возвращают
  • Выполняют только побочные эффекты
  • Не зависят от возвращаемого значения

Это помогает TypeScript:

  • Предотвращать ошибки типизации
  • Делать код более читаемым
  • Явно указывать намерения разработчика
  • Поддерживать контракт функции

Всегда указывай тип возврата, включая void!

Для чего использовать void? | PrepBro