Что означает ошибка «не назначается параметру типа никогда» в машинописном тексте?


205

Код:

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

Я получаю следующую ошибку TS:

[ts] Аргумент типа «строка» не может быть назначен параметру типа «никогда».

Что я делаю не так? Это ошибка?

Ответы:


310

Все, что вам нужно сделать, это определить свой resultмассив как строковый, как показано ниже:

const result : string[] = [];

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


7
Мне это кажется странным, почему по умолчанию never[]? есть ли в этом применение, кроме «массива, который ВСЕГДА будет пустым?»
Винсент Бускарелло

9
Я полностью согласен, потому что, честно говоря, я не могу придумать вариант использования, в котором массив nevers будет полезен. Но, изучая его, я наткнулся на этот ответ, в котором есть отличная информация.
Таэр М. Аль-Аджлуни 01

11
Разве тип по умолчанию не должен быть «любой»? Когда вы объявляете переменную ( let x;), она имеет тип anyпо умолчанию. Нет never.
Шахар Хар-Шув

1
Определенно можно было бы ожидать, что массив без типа будет any[]. Был удивлен, что это never[]делает его бесполезным. Неинтуитивно. Спасибо за ответ. редактировать: грамматика
Игорь Малык

4
@VincentBuscarello Полагаю, суть такого значения по умолчанию - заставить всегда добавлять типы в свои массивы; но сообщение об ошибке определенно бесполезно.
YakovL

36

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

const result = [] as  any;

11
На самом деле использование any- не лучший вариант, потому что он в основном отключает все функции TypeScript. Это обходной путь, который может привести к различным ошибкам.
Tomek Buszewski

2
Да. Но иногда все остальное не работает, особенно когда вы работаете со сторонними библиотеками ..
neomib

16

Похоже, это недавний регресс или какое-то странное поведение машинописного текста. Если у вас есть код:

const result = []

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

const result:any[] = []

однако, если в вашем tsconfig указано как noImplicitAnyЛОЖЬ, так и strictNullChecks ИСТИНА, это рассматривается как:

const result:never[] = []

ИМХО такое поведение противоречит всякой логике. Включение нулевой проверки изменяет типы записей в массиве ?? А потом включение noImplicitAnyфактически восстанавливает использование anyбез предупреждений ??

Когда у вас действительно есть массив any, вам не нужно указывать его дополнительным кодом.


11

У меня была такая же ошибка в функции ReactJS без статистики при использовании ReactJs Hook useState . Я хотел установить состояние массива объектов, поэтому, если я использую следующий способ

const [items , setItems] = useState([]);

и обновите состояние следующим образом:

 const item = { id : new Date().getTime() , text : 'New Text' };
 setItems([ item , ...items ]);

Я получал ошибку:

аргумент типа '{id: number; text: any} 'не может быть назначен параметру типа' never '

но если сделать это так,

const [items , setItems] = useState([{}]);

Ошибка исчезла, но есть элемент с индексом 0, который не имеет данных (не хочу этого).

так что решение, которое я нашел:

const [items , setItems] = useState([] as any);

11

Я получил ту же ошибку в функциональном компоненте ReactJS, используя перехватчик ReactJS useState. Решением было объявить тип useState при инициализации:

const [items , setItems] = useState<IItem[]>([]); // replace IItem[] with your own typing: string, boolean...

8

Решение, которое я нашел, было

const [files, setFiles] = useState([] as any);

1
Использование as anyмешает статической системе набора текста. Если вы знаете , какой тип или типы будут размещены в массиве, это гораздо лучше быть явным: const myArray: string[] = []; const [files, setFiles] = useState(myArray);. Обратите внимание, что в случае useState, вы можете вместо этого передать общий:const [files, setFiles] = useState<string[]>([]);
jmealy

6

Мне удалось обойти это, используя ключевое слово Array вместо пустых скобок:

const enhancers: Array<any> = [];

Использование:

if (typeof devToolsExtension === 'function') {
  enhancers.push(devToolsExtension())
}

Спасибо, что указали. ArrayКлючевое слово еще есть еще один хороший способ. Это даже более семантически полезно в случае, если вам нужно определить тип для такого массива массивов, как этотlet parsed: Array<[]> = [];
Валентин Ши


1

Удалите "strictNullChecks": true из "compilerOptions" или установите для него значение false в файле tsconfig.json вашего приложения Ng. Эти ошибки исчезнут, как и все остальное, и ваше приложение успешно скомпилируется.

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


Для меня tsconfig - это только "строгая" часть, когда я устанавливаю ее в false, когда вы говорите, что ошибка исчезнет, ​​и это в реакции, а не в angular. Спасибо.
Goran_Ilic_Ilke
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.