打字稿中的"不能分配类型永不参数"的错误是什么?

Lev*_*Lev 70 typescript

代码是:

const foo = (foo: string) => {
  const result = []
  result.push(foo)
}
Run Code Online (Sandbox Code Playgroud)

我收到以下TS错误:

[ts]类型'string'的参数不能分配给'never'类型的参数.

我究竟做错了什么?这是一个错误吗?

Tha*_*uni 103

您所要做的就是将您定义result为字符串数组,如下所示:

const result : string[] = [];
Run Code Online (Sandbox Code Playgroud)

  • 在没有定义数组类型的情况下,它默认为"never".因此,当您尝试向其添加"字符串"时,它是类型不匹配,因此它会抛出您看到的错误. (12认同)
  • 肯定会期望一个没有类型的数组是“any[]”。令人惊讶的是它是“never[]”,这使得它毫无用处。不直观。感谢你的回答。编辑:语法 (9认同)
  • @VincentBuscarello 我想,这种默认设置的要点是让一个人总是向其数组添加类型;但错误消息绝对没有帮助。 (8认同)
  • 谢谢,它的工作原理,但我仍然不明白错误是什么意思 (3认同)
  • 我完全同意,因为说实话,我想不出用例“从不”的数组会有用。但是在研究时,我遇到了这个[answer](/sf/answers/3445756541/),其中包含很多信息。 (3认同)
  • 默认类型不应该是“ any”吗?当您声明一个变量(`let x;`)时,其默认类型为“ any”。从来没有。 (3认同)
  • 我总是想知道这些更改在源代码中发生的位置,以便更好地理解,因此对于那些好奇的人,请参阅:https://github.com/Microsoft/TypeScript/issues/9976 和 https://github.com/microsoft/TypeScript/拉/8944 (3认同)
  • 在我看来,这很奇怪,为什么默认为`never []`?除了“总是会为空的数组”之外,还有什么用? (2认同)

nei*_*iya 33

我在 ReactJS 函数组件中遇到了同样的错误,使用 ReactJS useState 钩子。

解决方案是在初始化时使用尖括号声明 useState 的类型:

// Example: type of useState is an array of string
const [items , setItems] = useState<string[]>([]); 
Run Code Online (Sandbox Code Playgroud)


Sha*_*hah 30

const foo = (foo: string) => {
  const result: string[] = []
  result.push(foo)
}
Run Code Online (Sandbox Code Playgroud)

您需要指定数组是什么,因为result = []返回类型为any[]。通常,您希望避免使用any类型,因为根据 Microsoft 的说法,它们旨在用作“逃生舱口”。

结果是一个对象,它是 的数组string


Lak*_*chi 23

我找到的解决方案是

const [files, setFiles] = useState([] as any);
Run Code Online (Sandbox Code Playgroud)

  • 我不敢相信这个答案有这么多的赞成票,这基本上是沉默的打字稿,完全违背了它的目的。 (3认同)
  • 使用“as any”会阻碍静态类型系统。如果您知道数组中将包含什么类型,最好明确说明: `const myArray: string[] = []; const [文件,setFiles] = useState(myArray);`。请注意,在“useState”的情况下,您可以传入泛型,而不是:“const [files, setFiles] = useState&lt;string[]&gt;([]);” (2认同)

ImF*_*had 19

在使用 ReactJs Hook useState时,我在ReactJS statless 函数中 遇到了同样的错误。我想设置对象数组的状态,所以如果我使用以下方式

const [items , setItems] = useState([]);
Run Code Online (Sandbox Code Playgroud)

并像这样更新状态:

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

我收到错误:

'{ id: number; 类型的参数; 文本:任何 }' 都不能分配给类型为 'never' 的参数

但如果这样做,

const [items , setItems] = useState([{}]);
Run Code Online (Sandbox Code Playgroud)

错误消失了,但索引0的项目没有任何数据(不想要)。

所以我找到的解决方案是:

const [items , setItems] = useState([] as any);
Run Code Online (Sandbox Code Playgroud)

  • 实际上,我认为您的解决方案的更好版本是 const [items , setItems] = useState([] as string[]); (4认同)

roh*_*095 12

错误:“any”类型的参数不可分配给“never”类型的参数。

在 tsconfig.json 中 -

  "noImplicitReturns": false,

   "strictNullChecks":false,
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

解决方案:输入“从不”

在此输入图像描述


Mic*_*ers 9

我能够通过使用 Array 关键字而不是空括号来解决这个问题:

const enhancers: Array<any> = [];
Run Code Online (Sandbox Code Playgroud)

用:

if (typeof devToolsExtension === 'function') {
  enhancers.push(devToolsExtension())
}
Run Code Online (Sandbox Code Playgroud)


neo*_*mib 8

另一种方法是:

const result = [] as  any;
Run Code Online (Sandbox Code Playgroud)

  • 实际上使用“any”并不是一个好的选择,因为它基本上关闭了所有 TypeScript 功能。这是一种解决方法,可能会导致各种错误。 (26认同)
  • `const result: any[] = []` 不是更准确吗?它是任何非数组和被视为任何数组 (9认同)
  • 是的。但有时其他方法都不起作用,尤其是当您使用第三方库时。 (7认同)

小智 6

“compilerOptions”中删除“strictNullChecks”:true ,或在Ng 应用程序的tsconfig.json文件中将其设置为 false 。这些错误将会像任何事情一样消失,并且您的应用程序将成功编译。

免责声明:这只是一种解决方法。仅当空检查未正确处理时才会出现此错误,这在任何情况下都不是完成任务的好方法。


Ran*_*son 5

这似乎是最近的回归或打字稿中有些奇怪的行为。如果您有代码:

const result = []
Run Code Online (Sandbox Code Playgroud)

通常,您将其视为:

const result:any[] = []
Run Code Online (Sandbox Code Playgroud)

但是,如果您的tsconfig中同时具有noImplicitAnyFALSE和AND strictNullChecks TRUE,则将其视为:

const result:never[] = []
Run Code Online (Sandbox Code Playgroud)

这种行为违抗所有逻辑,恕我直言。启用空检查会更改数组的条目类型?然后开启noImplicitAny实际上会恢复使用,any而不会发出任何警告?

当您真正拥有的数组时any,您无需使用额外的代码进行指示。

  • 确实,这绝对是不直观的,称为“noimplicitany”的参数应该意味着任何时候某些东西都会被假定为any - 但事实并非如此。另外,隐式的“从不”似乎很愚蠢,为什么不简单地声明一个错误:数组没有声明其类型。恕我直言,这应该仅取决于 noImplicitAny,而不取决于组合。 (8认同)
  • 我认为,为大型回购做出贡献的人有时往往会对其进行过度设计。至少我们知道应该设置哪些标志以使其直观。对于我来说,我将两个标志都设置为 true 并且感觉很好。 (2认同)

Aks*_*ain 5

导致该错误的又一个原因。

如果您在使用 connect()() 包装组件后导出,则 props 可能会给出打字稿错误
解决方案:我没有进行太多探索,因为我可以选择用 useSelector 钩子替换 connect
函数

/* Comp.tsx */
interface IComp {
 a: number
}

const Comp = ({a}:IComp) => <div>{a}</div>

/* ** 

below line is culprit, you are exporting default the return 
value of Connect and there is no types added to that return
value of that connect()(Comp) 

** */

export default connect()(Comp)


--
/* App.tsx */
const App = () => {
/**  below line gives same error 
[ts] Argument of type 'number' is not assignable to 
parameter of type 'never' */
 return <Comp a={3} />
}
Run Code Online (Sandbox Code Playgroud)


Ber*_*rtC 5

我在定义(初始化)数组时遇到错误,如下所示:

let mainMenu: menuObjectInterface[] | [] = [];
Run Code Online (Sandbox Code Playgroud)

我遇到问题的代码:

let mainMenu: menuObjectInterface[] | [] = [];
dbresult.rows.forEach((m) => {
    if (!mainMenu.find((e) => e.menucode === m.menucode)) {
        // Not found in mainMenu, yet
        mainMenu.push({menucode: m.menucode, menudescription: m.menudescription})  // Here the error
    }
})
Run Code Online (Sandbox Code Playgroud)

错误是:TS2322:类型“any”不可分配给类型“never”

原因是该数组也是使用空数组选项进行初始化的。Typescript 看到了对也可以为空的类型的推送。因此出现了错误。

将行更改为此修复了错误:

let mainMenu: menuObjectInterface[] = [];
Run Code Online (Sandbox Code Playgroud)