首页 > 解决方案 > 如何修复递归reduce函数上的Typescript错误

问题描述

我是 Typescript 的新手,我写了一个非常基本的 JSON stringify 实现。代码按预期工作,但我的类型在递归字符串化嵌套数组的部分有点混乱。任何帮助表示赞赏:D

这是 TS 操场的链接,它显示了我得到的所有错误。 游乐场链接

type ValidJSON = ValidJSONObject | string | number | boolean | JsonArray

interface JsonArray extends Array<string | number | boolean | Date | ValidJSONObject | JsonArray> { }

interface ValidJSONObject {
    [x: string]: string | number | boolean | Date | JsonArray
}

export const stringify = (input: ValidJSON) :string => {
   if (input === null)
    return 'null'
  else if (input.constructor === String)
    return '"' + input.replace(/"|\n/g, (x:string) =>  x === '"' ? '\\"' :'\\n') + '"'
  else if (input.constructor === Number)
    return String(input)
  else if (input.constructor === Boolean)
    return input ? 'true' : 'false'
  else if (input.constructor === Array)
    return '[' + input.reduce((acc, v) => {
      if (v === undefined)
        return [...acc, 'null']
      else
        return [...acc, stringify(v)]
    }, []).join(',') + ']'
  else if (input.constructor === Object)
    return '{' + Object.keys(input).reduce((acc, k) => {
      if (input[k] === undefined)
        return acc
      else
        return [...acc, stringify(k) + ':' + stringify(input[k])]
    }, []).join(',') + '}'
  else
    return '{}'
};

标签: javascripttypescript

解决方案


如果无法推断累加器类型,reduce 方法需要类型参数。

例如。以下代码的累加器不告诉数组是什么类型。

[1,2,3].reduce((acc, cur) => ([...acc, cur+'']), [])

所以你需要像下面这样传递类型参数。

[1,2,3].reduce<string[]>((acc, cur) => ([...acc, cur+'']), [])

我还修复了所有错误。变化如下。

  1. 在 ValidJSON 类型定义中添加了 Date 类型。
  2. 添加string[]到 reduce 方法的类型参数。
  3. 将输入转换为(input as ValidJSONObject)

生成的 javascript 代码与您的相同。
我希望这个能帮上忙!

操场

type ValidJSON = ValidJSONObject | string | number | boolean | Date | JsonArray

interface JsonArray extends Array<string | number | boolean | Date | ValidJSONObject | JsonArray> { }

interface ValidJSONObject {
    [x: string]: string | number | boolean | Date | JsonArray
}

export const stringify = (input: ValidJSON) :string => {
   if (input === null)
    return 'null'
  else if (input.constructor === String)
    return '"' + input.replace(/"|\n/g, (x:string) =>  x === '"' ? '\\"' :'\\n') + '"'
  else if (input.constructor === Number)
    return String(input)
  else if (input.constructor === Boolean)
    return input ? 'true' : 'false'
  else if (input.constructor === Array)
    return '[' + input.reduce<string[]>((acc, v) => {
      if (v === undefined)
        return [...acc, 'null']
      else
        return [...acc, stringify(v)]
    }, []).join(',') + ']'
  else if (input.constructor === Object)
    return '{' + Object.keys(input).reduce<string[]>((acc, k: keyof ValidJSONObject) => {
      if ((input as ValidJSONObject)[k] === undefined)
        return acc
      else
        return [...acc, stringify(k) + ':' + stringify((input as ValidJSONObject)[k])]
    }, []).join(',') + '}'
  else
    return '{}'
};

推荐阅读