Що таке помилка "не присвоюється параметру типу ніколи" в typecript?


162

Код:

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

Я отримую таку помилку TS:

[ts] Аргумент типу 'string' не призначається параметру типу 'never'.

Що я роблю неправильно? Це помилка?

Відповіді:


253

Все, що вам потрібно зробити, це визначити свій resultмасив рядків, як:

const result : string[] = [];

Не визначаючи тип масиву, він за замовчуванням буде never. Отже, коли ви намагалися додати рядок до неї, це було невідповідність типу, і тому вона кинула помилку, яку ви побачили.


7
Мені це здається дивним, чому це за замовчуванням never[]? Чи є коли-небудь використання для цього, окрім "масиву, який ВЖЕ буде порожнім?"
— Вінсент Бускарелло

7
Я повністю згоден, тому що, якщо чесно, я не можу придумати випадок використання, який neverможе бути корисним масивом s. Але, дивлячись на це, я натрапив на цю відповідь, яка має чудову інформацію.
— Tha'er M. Al-Ajlouni

9
Чи не повинен тип за замовчуванням бути "будь-яким"? Коли ви оголошуєте змінну ( let x;), вона anyза замовчуванням має тип . Ні never.
— Шачар Хар-Шув

1
Однозначно буде очікувати масив без типу any[]. Був здивований, що це never[]робить його марним. Неінтуїтивні. Дякую за відповідь. редагувати: граматика
— Ігор Малик

4
@VincentBuscarello Я думаю, головний пункт такого дефолту - зробити так, щоб завжди додавати типи до своїх масивів; але повідомлення про помилку, безумовно, не корисне.
— ЯковЛ

28

Ще один спосіб:

const result = [] as  any;

8
Насправді використання anyне є хорошим варіантом, оскільки воно в основному вимикає будь-які функції TypeScript. Це вирішення і може призвести до різних помилок.
— Томек Бушевський

1
Так. Але іноді більше нічого не працює, особливо коли ти працюєш із сторонніми бібліотеками ..
— neomib

14

Це здається недавньою регресією чи якоюсь дивною поведінкою в машинописі. Якщо у вас є код:

const result = []

Зазвичай це трактується так, ніби ви написали:

const result:any[] = []

Однак, якщо у вас є і noImplicitAnyБРЕХНЯ, І strictNullChecks ІСТИНА в вашому TSconfig, він розглядається як:

const result:never[] = []

Така поведінка не відповідає всій логіці, ІМХО. Увімкнення нульових перевірок змінює типи входу масиву ?? А потім включення noImplicitAnyфактично відновлює використання anyбез будь-яких попереджень ??

Коли у вас справді є масив any, вам не потрібно вказувати його додатковим кодом.


10

У мене була така ж помилка в функції Statless 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);

7

Я отримав таку ж помилку в компоненті функції ReactJS, використовуючи гачок ReactJS useState. Рішенням було оголосити тип використаннядержави при ініціалізації:

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

3

Мені вдалося подолати це за допомогою ключового слова Array замість порожніх дужок:

const enhancers: Array<any> = [];

Використання:

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



1

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

Відмова від відповідальності : Це лише обхідний шлях. Ця помилка з’являється лише тоді, коли нульові перевірки не обробляються належним чином, що в будь-якому випадку не є хорошим способом втілення справ.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.