8

Что такое ошибка "не может быть присвоено параметру типа never" в TypeScript?

6

У меня есть следующий код на 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 ответ(ов)

11

Вам нужно просто определить ваш result как массив строк, вот так:

const result: string[] = [];

Если не определить тип массива, по умолчанию будет тип never. Поэтому, когда вы пытались добавить строку в массив, произошла ошибка несоответствия типов, из-за чего и возникла ошибка, которую вы увидели.

1

Другой способ:

const result: any[] = [];
1

Это действительно странное поведение в TypeScript, которое, похоже, связано с историческими причинами. Рассмотрим следующий код:

const result = []

Обычно его интерпретируют так, как если бы вы написали:

const result: any[] = []

Однако, если в вашем tsconfig установлены следующие настройки: noImplicitAny = FALSE и strictNullChecks = TRUE, это будет интерпретироваться как:

const result: never[] = []

Это поведение, на мой взгляд, противоречит здравому смыслу. Включение проверки на null изменяет типы массивов?? И, вдобавок, если включить noImplicitAny, это фактически восстанавливает использование any без каких-либо предупреждений??

Действительно, неинтуитивно, что добавление дополнительной проверки типа (noImplicitAny) приводит к более расслабленной проверке типов, особенно когда это вводит то, что вы пытались устранить.

1

Я столкнулся с той же ошибкой в функциональном компоненте React, используя хук useState.

Решение заключалось в том, чтобы явно указать тип для useState при инициализации, использовав угловые скобки:

// Пример: тип useState — это массив строк
const [items, setItems] = useState<string[]>([]);
0

В вашем примере кода вы определяете массив result с помощью result = [], и TypeScript интерпретирует его тип как any[]. Чтобы избежать этого, вам нужно явно указать тип элементов, которые будут храниться в массиве. Это поможет сделать ваш код более строгим и безопасным, так как использование типа any обычно не рекомендуется, поскольку он служит скорее "вытяжкой" для обхода типизации, как указано в документации Microsoft.

Правильный способ определения массива строк в вашем случае будет выглядеть так:

const foo = (foo: string): void => {
  const result: string[] = [];
  result.push(foo);
}

Теперь тип result явно указан как string[], что означает, что этот массив будет содержать только строки. Таким образом, ваш код станет более читаемым и предупреждающим об ошибках во время компиляции.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь