【发布时间】:2019-02-24 16:33:22
【问题描述】:
代码是:
const foo = (foo: string) => {
const result = []
result.push(foo)
}
我收到以下 TS 错误:
[ts] 'string' 类型的参数不可分配给'never' 类型的参数。
我做错了什么?这是一个错误吗?
【问题讨论】:
标签: typescript
代码是:
const foo = (foo: string) => {
const result = []
result.push(foo)
}
我收到以下 TS 错误:
[ts] 'string' 类型的参数不可分配给'never' 类型的参数。
我做错了什么?这是一个错误吗?
【问题讨论】:
标签: typescript
如下定义(初始化)数组时出现错误:
let mainMenu: menuObjectInterface[] | [] = [];
我遇到问题的代码:
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
}
})
错误是:TS2322:类型“any”不可分配给类型“never”
原因是该数组也使用空数组选项进行了初始化。 Typescript 看到了一个也可以为空的类型的推送。因此出现错误。
将行更改为此修复了错误:
let mainMenu: menuObjectInterface[] = [];
【讨论】:
假设您的 linter 可以使用“任何”类型:
如果您不知道将填充数组的值的类型,您可以这样做,result 将推断类型。
const result: any[] = []
【讨论】:
您只需将结果定义为任意数组,如下所示:
结果:任意 = [];
【讨论】:
这似乎是打字稿中的一些奇怪行为,由于遗留原因,他们一直坚持。如果你有代码:
const result = []
通常会被视为您写的:
const result:any[] = []
但是,如果您的 tsconfig 中同时具有 noImplicitAny FALSE、AND strictNullChecks TRUE,则将其视为:
const result:never[] = []
这种行为违反了所有逻辑,恕我直言。打开空检查会更改数组的条目类型??然后开启noImplicitAny居然恢复使用any没有任何警告??
当您确实有一个 any 数组时,您不需要用额外的代码来表示它。
【讨论】:
您也可以添加as string[]
const foo = (foo: string) => {
const result = []
(result as string[]).push(foo)
}
当它是对象的一部分时我这样做了
let complexObj = {
arrData : [],
anotherKey: anotherValue
...
}
(arrData as string[]).push('text')
【讨论】:
我在 ReactJS 函数组件中遇到了同样的错误,使用 ReactJS useState 钩子。
解决方案是在初始化时使用尖括号声明 useState 的类型:
// Example: type of useState is an array of string
const [items , setItems] = useState<string[]>([]);
【讨论】:
错误的另一个原因。
如果您在使用 connect()() 包装组件后导出,则 props 可能会出现打字稿错误解决方案:我没有探索太多,因为我可以选择用 useSelector 钩子替换连接函数
例如
/* 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} />
}
【讨论】:
我找到的解决方案是
const [files, setFiles] = useState([] as any);
【讨论】:
as any 会阻止静态类型系统。如果您知道数组中将包含哪些类型,最好明确表示:const myArray: string[] = []; const [files, setFiles] = useState(myArray);。注意在useState的情况下,你可以传入一个泛型,而不是:const [files, setFiles] = useState<string[]>([]);
as any,您只是在说“不,我不想使用打字稿”。另一方面,宁亚的回答已经足够好了。更好的方法应该是接口,但我也是打字稿的新手,所以我不确定如何接口这个。
从 "compilerOptions" 中删除 "strictNullChecks": true 或在 中将其设置为 false >tsconfig.json 文件的 Ng 应用程序。这些错误会像任何事情一样消失,您的应用会成功编译。
免责声明:这只是一种解决方法。仅当未正确处理空检查时才会出现此错误,这在任何情况下都不是完成工作的好方法。
【讨论】:
我在使用 ReactJs Hook 时在 ReactJS statless 函数中遇到了同样的错误 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);
【讨论】:
您所要做的就是将您的result 定义为一个字符串数组,如下所示:
const result : string[] = [];
不定义数组类型,默认为never。因此,当您尝试向其添加字符串时,它是类型不匹配的,因此会引发您看到的错误。
【讨论】:
never[] ?除了“一个永远为空的数组”之外,还有什么用处?
nevers 数组会有用的用例。但是在调查它时,我发现了这个answer,它有很好的信息。
let x;) 时,默认情况下它的类型为 any。不是never。
我能够通过使用 Array 关键字而不是空括号来解决这个问题:
const enhancers: Array<any> = [];
用途:
if (typeof devToolsExtension === 'function') {
enhancers.push(devToolsExtension())
}
【讨论】:
Array 关键字是另一种好方法。如果您必须为这样的数组数组定义一个类型,它在语义上更有用let parsed: Array<[]> = [];
另一种方法是:
const result = [] as any;
【讨论】:
any 不是一个好的选择,因为它基本上会关闭任何 TypeScript 功能。这是一种解决方法,可能会导致各种错误。
const result: any[] = [] 会更准确吗?它是一个任意非数组,并且数组被视为任意
您需要在字符串数组const result: string[] = []; 中键入result。
【讨论】: