目录
Argument of type not assignable to parameter type ‘never’
本文涵盖 3 个错误,因此请确保根据您使用的是 TypeScript 还是 React.js 单击与您相关的副标题。
不可分配给参数类型 ‘never’ 的参数类型
当我们声明一个空数组而不显式键入它并尝试向其中添加元素时,会发生错误“Argument of type is not assignable to parameter of type ‘never’”。
要解决该错误,请显式键入空数组,例如
const arr: string[] = [];
.
以下是错误发生方式的 2 个示例。
const arr = []; // ⛔️ Error: Argument of type 'number' is not assignable to parameter of type 'never'.ts(2345) arr.push(100); // --------------------------------------- const obj = { arr: [], }; // ⛔️ Argument of type 'string' is not assignable to parameter of type 'never'.ts(2345) obj.arr.push('one');
我们声明了一个空数组,并为它分配了一个类型never[]
。此类型表示一个永远不会包含任何元素
(始终为空)的数组
。
显式键入数组解决错误
要解决该错误,
请显式键入空数组。
const arr: number[] = []; arr.push(100); console.log(arr); // 👉️ [100] // --------------------------------------- type MyType = { arr: string[]; }; const obj: MyType = { arr: [], }; obj.arr.push('one'); // 👇️ {arr: ['one']} console.log(obj);
我们将第一个数组键入为number[]
. 换句话说,一个只包含数字元素的数组。
const arr: number[] = [];
arr
第二个示例中的属性是一个包含字符串 – 的
数组string[]
。
我已经写了一篇关于如何在 TS 中为类型化变量声明空数组的详细指南
。
使用any
类型来禁用类型检查
如果您不知道数组包含什么类型的元素并且想禁用类型检查,请将数组键入为any[]
.
const arr: any[] = []; arr.push(100); arr.push('hello'); arr.push({ name: 'James' }); // 👇️ [100, 'hello', {name: 'James'}] console.log(arr);
这有效地
禁用了类型检查,这意味着数组可以包含任何类型的元素。
输入一个对象数组
下面是一个如何键入
对象数组的示例。
const arr: { id: number; name: string }[] = []; arr.push({ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }); // 👇️ [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}] console.log(arr);
数组中的每个对象都包含id
和name
属性。
type Person = { id: number; name: string; }; const arr: Person[] = []; arr.push({ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }); // 👇️ [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}] console.log(arr);
如果您需要键入一组对象,请查看我的
详细指南。
一个空数组被推断为具有一种类型never[]
发生错误是因为当我们声明一个空数组时,TypeScript 将其类型推断为never[]
– 一个永远不会包含任何元素的数组。
// 👇️ const arr: never[] const arr = []; // 👇️ const obj: { // arr: never[]; // } const obj = { arr: [], };
tsconfig.json
在你的文件中改变这个行为
但是,TypeScript 会根据tsconfig.json文件中的设置以不同方式推断存储空数组的变量类型
。
当您设置noImplicitAny
为false
和strictNullChecks
为时true
,空数组的类型被推断为never[]
。
{ "compilerOptions": { "strictNullChecks": true, "noImplicitAny": false, // ... rest } }
但是,如果我切换noImplicitAny
到true
,存储空数组的变量的类型被推断为any[]
。
{ "compilerOptions": { "strictNullChecks": true, "noImplicitAny": true, // ... rest } }
现在arr
变量被推断为any[]
。
// 👇️ const arr: any[] 👇️ const arr = []; // 👇️ const obj: { // arr: never[]; // } const obj = { arr: [], };
请注意,存储空数组的变量现在具有推断类型
any[]
.
换句话说,一个禁用类型检查的数组(可以包含任何类型的元素)。
但是,对象中的空数组属性仍然是 type never[]
。
noImplicitAny
选项会导致 TypeScript 在不存在值的类型注释时发出错误,因此它必须
隐式地将其类型推断为any
.
这种行为非常不直观,最好不要依赖这样的东西。
您可以依靠 TypeScript 来推断您声明为内联的文字类型(例如字符串和数字),但对数组或对象这样做绝不是一个好主意。
如果您尝试访问类型为 的值的属性never
,您将收到
类型“从不”的属性不存在的
错误。
如果您收到错误Type is not assignable to type ‘never’ in
React.js,请单击以下子标题:
类型不可分配给 TypeScript 中的类型 ‘never’
当我们声明一个空数组而不显式键入它并尝试改变数组时,会出现错误“Type is not assignable to type ‘never’”。
要解决该错误,请显式键入空数组。
下面是错误如何发生的示例。
// 👇️ const arr: never[] const arr = []; // ⛔️ Error: Type 'string' is not assignable to type 'never'.ts(2322) arr[0] = 'a';
我们声明了一个空数组,并为它分配了一个类型never[]
。此类型表示一个永远不会包含任何元素(始终为空)的数组。
显式键入数组解决错误
要解决此问题,请显式键入空数组。
const arr: string[] = []; arr[0] = 'a'; console.log(arr); // 👉️ ['a']
我们将数组键入为string[]
,换句话说,一个仅包含字符串的数组。
如果您不知道您的数组包含什么类型的元素并且想禁用类型检查,您可以将其键入为any[]
.
const arr: any[] = []; arr[0] = 'a'; arr[1] = 100; arr[2] = { department: 'development' }; // 👇️ ['a', 100, {department: 'development'}] console.log(arr);
这有效地
禁用了类型检查,这意味着数组可以包含任何类型的元素。
下面是一个如何键入对象数组的示例。
const arr: { name: string; salary: number }[] = []; arr[0] = { name: 'Tom', salary: 100 }; arr[1] = { name: 'Tim', salary: 200 }; // 👇️ [{name: 'Tom', salary: 100}, {name: 'Tim', salary: 200}] console.log(arr);
数组中的每个对象都具有name
和salary
属性。
type Employee = { name: string; salary: number; tasks: string[]; }; const arr: Employee[] = []; arr[0] = { name: 'Tom', salary: 100, tasks: ['task 1'] }; arr[1] = { name: 'Tim', salary: 200, tasks: ['task 2', 'task 3'] };
发生错误的原因是当我们声明一个空数组时,TypeScript 将其类型推断为never[]
– 一个永远不会包含任何元素的数组。
// 👇️ const arr: never[] const arr = []; // 👇️ const employee: { // tasks: never[]; // } const employee = { tasks: [], };
如果您想阅读更多有关为类型化变量声明空数组的信息,请查看以下文章。
noImplicitAny
中的设置tsconfig.json
但是,TypeScript 会根据文件中的设置以不同方式推断存储空数组的变量类型tsconfig.json
。
当您设置noImplicitAny
为false
和strictNullChecks
为时true
,空数组的类型被推断为never[]
。
{ "compilerOptions": { "strictNullChecks": true, "noImplicitAny": false, // ... rest } }
但是,如果我切换noImplicitAny
到true
,存储空数组的变量的类型被推断为any[]
。
{ "compilerOptions": { "strictNullChecks": true, "noImplicitAny": true, // ... rest } }
现在arr
变量被推断为any[]
。
// 👇️ const arr: any[] const arr = []; // 👇️ const employee: { // tasks: never[]; // } const employee = { tasks: [], };
请注意,存储空数组的变量现在具有推断类型
any[]
,换句话说,一个禁用类型检查的数组(可以包含任何类型的元素)。
但是,对象中的空数组属性仍然是 type never[]
。
noImplicitAny
选项会导致 TypeScript 在不存在值的类型注释时发出错误,因此它必须隐式地将其类型推断为any
.
这种行为非常不直观,最好不要依赖这样的东西。
您可以依靠 TypeScript 来推断您声明为内联的文字类型(例如字符串和数字),但对数组或对象这样做绝不是一个好主意。
类型不可分配给 React 中的类型 ‘never’
useState
当我们用钩子声明一个空状态数组但不键入数组时,会出现错误“Type is not assignable to type ‘never’” 。
要解决该错误,请使用泛型来键入状态数组。
下面是错误如何发生的示例。
import {useState} from 'react'; function App() { // 👇️ arr is never[] const [arr, setArr] = useState([]); // ⛔️ Error: Type 'number' is not assignable to type 'never'.ts(2322) setArr([1, 2, 3]); return ( <div className="App"> <div>Hello world</div> </div> ); } export default App;
错误是因为我们声明了一个空状态数组而没有显式键入它。
never[]
,换句话说,一个永远为空的数组,这不是我们想要的。使用泛型键入状态数组
要解决该错误,请在useState挂钩上使用泛型
来键入状态数组。
import {useState} from 'react'; function App() { // 👇️ type the array with the generic const [arr, setArr] = useState<any[]>([]); setArr([1, 2, 3]); return ( <div className="App"> <div>Hello world</div> </div> ); } export default App;
我们使用了非常广泛的 类型any[]
,它是一个包含任何类型元素的数组。
在可能的情况下,越具体越好。
import {useState} from 'react'; function App() { // 👇️ array of strings const [strArr, setStrArr] = useState<string[]>([]); // 👇️ an array of objects const [objArr, setObjArr] = useState<{name: string; age: number}[]>([]); setStrArr(['a', 'b', 'c']); setObjArr([{name: 'A', age: 1}]); return ( <div className="App"> <div>Hello world</div> </div> ); } export default App;
上面的示例显示了如何将状态数组键入为字符串数组或对象数组。
使用 TypeScript 时,始终确保在 React 中显式键入空数组。
如果您收到包含
never类型的错误消息,则很有可能您忘记了显式键入一个值,并且它被推断为具有never
.
useState
。如果您输入的是基本 TypeScript 变量,只需用冒号分隔变量名称及其类型。
function App() { // 👇️ declare array of strings const arr: string[] = []; arr.push('a', 'b', 'c'); return ( <div className="App"> <div>Hello world</div> </div> ); } export default App;
我还写了一篇关于
如何将 useState 键入为数组或对象的详细文章。
额外资源
您可以通过查看以下教程来了解有关相关主题的更多信息: