Что такое ошибка "не может быть присвоено параметру типа never" в TypeScript?
У меня есть следующий код на TypeScript:
const foo = (foo: string) => {
const result = []
result.push(foo)
}
При компиляции я получаю следующую ошибку TS:
[ts] Argument of type 'string' is not assignable to parameter of type 'never'.
Не могу понять, что именно я делаю неправильно. Это ошибка в коде или это баг в TypeScript? Не могли бы вы помочь разобраться?
5 ответ(ов)
Вам нужно просто определить ваш result
как массив строк, вот так:
const result: string[] = [];
Если не определить тип массива, по умолчанию будет тип never
. Поэтому, когда вы пытались добавить строку в массив, произошла ошибка несоответствия типов, из-за чего и возникла ошибка, которую вы увидели.
Другой способ:
const result: any[] = [];
Это действительно странное поведение в TypeScript, которое, похоже, связано с историческими причинами. Рассмотрим следующий код:
const result = []
Обычно его интерпретируют так, как если бы вы написали:
const result: any[] = []
Однако, если в вашем tsconfig
установлены следующие настройки: noImplicitAny
= FALSE и strictNullChecks
= TRUE, это будет интерпретироваться как:
const result: never[] = []
Это поведение, на мой взгляд, противоречит здравому смыслу. Включение проверки на null
изменяет типы массивов?? И, вдобавок, если включить noImplicitAny
, это фактически восстанавливает использование any
без каких-либо предупреждений??
Действительно, неинтуитивно, что добавление дополнительной проверки типа (noImplicitAny
) приводит к более расслабленной проверке типов, особенно когда это вводит то, что вы пытались устранить.
Я столкнулся с той же ошибкой в функциональном компоненте React, используя хук useState.
Решение заключалось в том, чтобы явно указать тип для useState при инициализации, использовав угловые скобки:
// Пример: тип useState — это массив строк
const [items, setItems] = useState<string[]>([]);
В вашем примере кода вы определяете массив result
с помощью result = []
, и TypeScript интерпретирует его тип как any[]
. Чтобы избежать этого, вам нужно явно указать тип элементов, которые будут храниться в массиве. Это поможет сделать ваш код более строгим и безопасным, так как использование типа any
обычно не рекомендуется, поскольку он служит скорее "вытяжкой" для обхода типизации, как указано в документации Microsoft.
Правильный способ определения массива строк в вашем случае будет выглядеть так:
const foo = (foo: string): void => {
const result: string[] = [];
result.push(foo);
}
Теперь тип result
явно указан как string[]
, что означает, что этот массив будет содержать только строки. Таким образом, ваш код станет более читаемым и предупреждающим об ошибках во время компиляции.
Как явно задать новое свойство у `window` в TypeScript?
Как преобразовать строку в число в TypeScript?
Как конвертировать строку в enum в TypeScript?
Как удалить элемент массива в TypeScript?
'unknown' против 'any': в чем разница?