Перейти к содержанию

Ошибки

В этом разделе мы обсудим, как читать и понимать ошибки TypeScript. Мы следим за распространенными ошибками и их решениями.

Ошибки интерпретации

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

Давайте рассмотрим пример в среде IDE, чтобы разбить на части процесс чтения сообщения об ошибке.

type SomethingComplex = {
    foo: number;
    bar: string;
};
function takeSomethingComplex(arg: SomethingComplex) {}
function getBar(): string {
    return 'some bar';
}

//////////////////////////////////
// Пример возникновения ошибки
//////////////////////////////////
const fail = {
    foo: 123,
    bar: getBar,
};

takeSomethingComplex(fail); // TS ОШИБКА ПРОИСХОДИТ ЗДЕСЬ

Этот пример демонстрирует распространенную ошибку программистов, когда они не могут вызвать функцию (bar: getBar должно быть bar: getBar()). К счастью, эта ошибка обнаруживается TypeScript, когда требования к типу не совпадают.

Категории ошибок

Есть две категории сообщений об ошибках TypeScript (краткие и подробные).

Краткие описания

Цель краткого сообщения об ошибке - предоставить пример шаблонного описания компилятором номера ошибки и сообщения. В этом примере краткое сообщение выглядит так:

TS2345: Аргумент типа '{ foo: number; bar: () => string; }'
не может быть присвоен параметру типа 'SomethingComplex'.

Это довольно понятное объяснение ошибки. Однако он не дает более подробного объяснения, почему произошла ошибка. Вот для чего нужно подробное сообщение об ошибке.

Подробные описания

Для этого примера подробная версия ошибки выглядит так:

[ts]
Аргумент типа '{ foo: number; bar: () => string; }' не может
быть присвоен параметру типа 'SomethingComplex'.
  Типы свойства 'bar' несовместимы.
    Тип '() => string' не может быть присвоен типу 'string'.

Целью подробного сообщения об ошибке является указать пользователю причину возникновения той или иной ошибки (в данном случае несовместимости типов). Первая строка такая же, как и в кратком сообщении, за ней следует цепочка. Вы должны читать эту цепочку как серию ответов на вопрос разработчика ПОЧЕМУ, т.е.

ОШИБКА: Аргумент типа '{ foo: number; bar: () => string; }'
не может быть присвоен параметру типа 'SomethingComplex'.

ПОЧЕМУ?
ПО ПРИЧИНЕ ОШИБКИ: Типы свойства 'bar' несовместимы.

ПОЧЕМУ?
ПО ПРИЧИНЕ ОШИБКИ: Тип '() => string' не может быть присвоен типу 'string'.

Итак, основная причина в том,

  • для свойства bar
  • существует функция () => string в то время как это ожидался string.

Это должно помочь разработчику исправить ошибку свойства bar (они забыли вызвать функцию ()).

Как это отображается во подсказках IDE

IDE обычно показывает подробное описание, за которым следует краткая версия во всплывающей подсказке, как показано ниже:

IDE пример сообщения об ошибке

  • Обычно вы просто читаете подробную версию, образующую цепочку ПОЧЕМУ? в вашей голове.
  • Используйте краткую версию, если хотите найти похожие ошибки (используя код ошибки TSXXXX или части сообщения об ошибке)

Распространенные ошибки

В этом разделе мы объясняем ряд распространенных кодов ошибок, с которыми разработчики сталкиваются в реальной жизни.

TS2304

Примеры:

Невозможно найти имя ga > Невозможно найти имя $ > Невозможно найти модуль jquery

Вы, вероятно, используете стороннюю библиотеку (например google analytics) и не объявили это. TypeScript пытается спасти вас от орфографических ошибок и использования переменных без их объявления, вы подключаете внешнюю библиотеку, поэтому вам нужно сделать ее доступной во время выполнения (подробнее о том, как это исправить).

TS2307

Пример:

Невозможно найти модуль 'underscore'

Вероятно, вы используете стороннюю библиотеку (например underscore) как модуль (подробнее о модулях) и у вас нет для него файла объявления среды (подробнее об объявлениях среды).

TS1148

Пример:

Невозможно скомпилировать модули, если не указан флаг '--module'

Ознакомьтесь с разделом модули.

Переменная условия catch не может иметь описание типа

Пример:

try { something(); }
catch (e: Error) { // Переменная условия catch не может иметь описание типа
}

TypeScript защищает вас от ошибочного кода JavaScript. Вместо этого используйте защиту типа:

try {
    something();
} catch (e) {
    if (e instanceof Error) {
        // Вот, пожалуйста.
    }
}

Интерфейс ElementClass не может одновременно расширять типы Component и Component

Это происходит, когда у вас есть два модуля react.d.ts (@types/react/index.d.ts) в контексте компиляции.

Fix:

  • Удалите node_modules и все package-lock (или yarn lock) и снова запустите npm install.
  • Если это не сработает, найдите невалидный модуль (все модули, используемые вашим проектом, должны иметь react.d.ts как peerDependency, а не жесткую dependency) и сообщите об этом команде разработчиков этого модуля.