typescript 为递归调用定义正确的类型

wqlqzqxt  于 2023-02-20  发布在  TypeScript
关注(0)|答案(1)|浏览(166)

我已经定义了一个函数,它递归地遍历嵌套对象(或非嵌套对象)并查找特定键,提取其值

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
            }
         }
      }, [])
}
wydwbb8l

wydwbb8l1#

当你使用reduce时,如果初始化器是一个空的数据结构,你需要Assert它的类型,否则TS将不允许你填充它,因为累加器和初始化器需要是相同的类型。
我让您弄清楚它应该是什么类型,但是尝试让starterAssert[] as any[],错误就会消失。
现在,如果我可以给予意见/建议:当您可以在以下上下文中使用push时,请不要使用concat:你正在推到一个新数组,reduce表达式仍然是纯的,并且在它里面没有可观察到的副作用,但是这样更有效。

相关问题