Топ ошибок начинающих TypeScript разработчиков

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Топ ошибок начинающих TypeScript разработчиков

TypeScript — это мощный инструмент, который помогает писать более надёжный и поддерживаемый код. Однако, как и любой язык, он таит в себе ловушки, особенно для новичков. Многие разработчики приходят из JavaScript и продолжают использовать старые привычки, сводя на нет преимущества статической типизации. В этой статье мы разберём 4 самые частые ошибки начинающих TypeScript разработчиков, покажем, как их исправить, и дадим практические советы. Если вы только начинаете свой путь с TypeScript, эта статья поможет вам избежать типичных граблей.

1. Злоупотребление типом any

Самая распространённая ошибка — использование any везде, где TypeScript не может вывести тип автоматически. Начинающие часто пишут так:

function processData(data: any) {
    console.log(data.name.toUpperCase());
}

Это полностью отключает проверку типов для переменной data. Вы теряете все преимущества TypeScript: автодополнение, проверку на ошибки и документацию кода.

Что делать вместо этого?

Всегда старайтесь явно описать тип, даже если он сложный. Используйте unknown, если тип действительно неизвестен на момент написания кода:

function processData(data: unknown) {
    if (typeof data === 'object' && data !== null && 'name' in data) {
        console.log((data as { name: string }).name.toUpperCase());
    }
}

Или, ещё лучше, опишите интерфейс:

interface DataItem {
    name: string;
    age?: number;
}

function processData(data: DataItem) {
    console.log(data.name.toUpperCase());
}

Совет: Настройте noImplicitAny: true в tsconfig.json. Компилятор будет ругаться на любое неявное any, и вы привыкнете писать типы.

2. Игнорирование strictNullChecks

В JavaScript null и undefined — это обычные значения. В TypeScript без строгих проверок вы можете случайно обратиться к свойству null и получить ошибку в рантайме. Типичная ошибка:

function getLength(str: string | null) {
    return str.length; // Ошибка: Object is possibly 'null'
}

Если strictNullChecks выключен, TypeScript не предупредит вас, и ошибка проявится только в рантайме.

Решение: Включите strict: true в tsconfig.json. Это автоматически активирует strictNullChecks. Теперь TypeScript заставит вас обрабатывать null и undefined:

function getLength(str: string | null): number {
    if (str === null) {
        return 0;
    }
    return str.length;
}

// Или используйте optional chaining и nullish coalescing:
function getLengthSafe(str: string | null): number {
    return str?.length ?? 0;
}

Важно: Никогда не отключайте strictNullChecks. Это одна из главных фич TypeScript, которая предотвращает миллионы багов.

3. Неправильная работа с async/await и промисами

TypeScript строго типизирует асинхронные функции, но новички часто забывают про возвращаемый тип Promise. Пример ошибки:

async function fetchUser(id: number) {
    const response = await fetch(`/api/users/${id}`);
    return response.json(); // TypeScript может не знать точный тип
}

Здесь response.json() возвращает Promise<any>, и вы снова теряете типизацию. Вторая распространённая проблема — забыть обработать ошибки:

async function loadData() {
    const data = await fetchUser(1); // Если fetch упал, ошибка не обработана
    console.log(data.name);
}

Как правильно?

Всегда явно указывайте возвращаемый тип асинхронной функции и обрабатывайте ошибки:

interface User {
    id: number;
    name: string;
}

async function fetchUser(id: number): Promise<User> {
    const response = await fetch(`/api/users/${id}`);
    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json() as Promise<User>;
}

async function loadData() {
    try {
        const data = await fetchUser(1);
        console.log(data.name);
    } catch (error) {
        console.error('Failed to load user:', error);
    }
}

Используйте дженерики для типизации ответов от API — это сделает код предсказуемым.

4. Избыточная или недостаточная типизация

Новички часто впадают в крайности: либо пишут типы везде, где можно и нельзя, либо вообще их не пишут. Пример избыточности:

const num: number = 5; // Избыточно, TypeScript сам выведет number
const add = (a: number, b: number): number => a + b; // Возвращаемый тип можно не указывать

С другой стороны, недостаточная типизация проявляется в функциях, где параметры имеют тип any или объекты не описаны интерфейсами.

Золотое правило: Позволяйте TypeScript выводить типы там, где это очевидно (примитивы, простые выражения), но всегда явно типизируйте:

  • Параметры функций
  • Возвращаемые типы публичных функций (для документации)
  • Сложные структуры данных (интерфейсы, типы)
  • Границы модулей (экспортируемые функции и классы)

Пример хорошего баланса:

interface Config {
    url: string;
    timeout?: number;
}

function createConnection(config: Config): Connection {
    // TypeScript выведет тип возвращаемого значения из реализации
    return new Connection(config.url, config.timeout ?? 5000);
}

Используйте typeof и keyof для динамической типизации, но не злоупотребляйте сложными дженериками, пока не освоите базу.

Заключение

TypeScript создан, чтобы помогать разработчику, а не мешать. Избегая этих четырёх ошибок — злоупотребления any, игнорирования strictNullChecks, неправильной работы с асинхронностью и дисбаланса в типизации — вы сделаете свой код надёжнее, чище и

Блоги

Рекомендаций по книгам