我已经定义了一个函数,它递归地遍历嵌套对象(或非嵌套对象)并查找特定键,提取其值
const findName = <T extends object>(obj: T, keyToFind: string): T[] => {
return Object.entries(obj)
.reduce((acc, [key, value]) => {
if(key === keyToFind) {
return acc.concat(value)
} else {
//is the next level of nesting an object so we can keep recursively searching for the key?
if (typeof value === 'object') {
return acc.concat(findName(value, keyToFind)) //problem is here because value is of type any
} else {
return acc
}
}
}, [])
}
我正在尝试为value
定义一个类型,因为当我在递归步骤中调用findName
时,我得到了以下错误
No overload matches this call.
Overload 1 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
Argument of type 'any[]' is not assignable to parameter of type 'ConcatArray<never>'.
The types returned by 'slice(...)' are incompatible between these types.
Type 'any[]' is not assignable to type 'never[]'.
Type 'any' is not assignable to type 'never'.
Overload 2 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
Argument of type 'any[]' is not assignable to parameter of type 'ConcatArray<never>'.
我不确定如何定义一个类型,所以编译器不再抱怨这个问题。
这是当前场景的Playground
谢谢
- 更新**
我通过将reduce的泛型类型设置为T[]
,成功地对该错误进行了排序,但value
仍然是any类型,因此开始出现linting,是否有办法在连接时将其定义为字符串
const findName = <T extends object>(obj: T, keyToFind: string): T[] => {
return Object.entries(obj)
.reduce<T[]>((acc, [key, value]) => {
if(key === keyToFind) {
return acc.concat(value)
} else {
//is the next level of nesting an object so we can keep recursively searching for the key?
if (typeof value === 'object') {
return acc.concat(findName(value, keyToFind))
} else {
return acc
}
}
}, [])
}
1条答案
按热度按时间wydwbb8l1#
当你使用
reduce
时,如果初始化器是一个空的数据结构,你需要Assert它的类型,否则TS将不允许你填充它,因为累加器和初始化器需要是相同的类型。我让您弄清楚它应该是什么类型,但是尝试让starterAssert
[] as any[]
,错误就会消失。现在,如果我可以给予意见/建议:当您可以在以下上下文中使用
push
时,请不要使用concat
:你正在推到一个新数组,reduce表达式仍然是纯的,并且在它里面没有可观察到的副作用,但是这样更有效。