Javascript 如何更改在TypeScript中编写方法

Javascript 如何更改在TypeScript中编写方法,javascript,typescript,Javascript,Typescript,我用typescript写了这个方法,但是我被重复的内容所困扰。我想写得更好,大致是这样的: public renameJson(json: any): any { return Object.keys(json).reduce( (s, item) => this.isUpperCase(item.charAt(1)) ? { ...s, [item.toLowerCase(

我用typescript写了这个方法,但是我被重复的内容所困扰。我想写得更好,大致是这样的:

 public renameJson(json: any): any {
    return Object.keys(json).reduce(
      (s, item) =>
        this.isUpperCase(item.charAt(1))
          ? {
              ...s,
              [item.toLowerCase()]: this.getTransform(json[item])
            }
          : {
              ...s,
              [this.getFirstLetterToLowerCase(item)]: this.getTransform(
                json[item]
              )
            },
      {}
    );
  }

但是我的编译器说这是一个错误,我不知道为什么。

这里发生了一些不同的事情

TL;博士:

public renameJson2(json: any): any {
    return Object.keys(json).reduce(
        (s, item) =>
        {
            ...s,
            [
                this.isUpperCase(item.charAt(1))
                ? item.toLowerCase()
                : this.getFirstLetterToLowerCase(item)
            ]
            : this.getTransform(json[item])
        },
        {}
    );
}
你必须填补你自己的空缺,但问题是

与原件有关的问题:

  • 不带主体的arrow函数返回的对象应包装在paren中,以避免解析器将其与函数主体混淆
  • Array.prototype.reduce的回调得到四个参数(累加器、item、数组、thisValue),而不是两个
  • 在签名中使用
    any
    将涉及大量的强制转换,因此我添加了一个通用对象接口
  • 简洁是好的,但可读性更好。不要害怕有意义的临时变量,同样在数组方法中,抖动可能会在第一次或第二次传递后优化它们

  • 这是因为您为正在构造的对象准备的花括号被视为
    reducer
    函数的花括号。您只需在reducer函数中为如下对象添加一个
    return
    语句-

    interface IPojo {
      [key: string]: any
    }
    
    class Foo {
      public getTransform(...xs: any[]) {
        return xs;
      }
    
      public renameJson2(json: IPojo): IPojo {
        return Object.keys(json).reduce(
          (obj: IPojo, item: string, ...xtra: any[]) => {
            const [first, ...rest] = item.split('');
            // I don't have your other methods, so replace this
            // regex check if you wish.
            const key = first.match(/[A-Z]/)
              ? item.toLowerCase()
              : first.toLowerCase() + rest.join('');
    
            obj[key] = this.getTransform(json[item]);
            return obj;
          }, {}
        );
      }
    }
    

    首先,解决您看到的问题。问题是,当在一个箭头函数后使用大括号时,JS希望出现一个函数体。这就是你写的东西

     return Object.keys(json).reduce(
        (s, item) =>
        {
           return { ...s,
            [
                this.isUpperCase(item.charAt(1))
                ? item.toLowerCase()
                : this.getFirstLetterToLowerCase(item)
            ]
            : this.getTransform(json[item]) 
            }
        },
       {}
     );
    
    我将arrow函数转换为普通函数,以便您可以看到TS所看到的内容

    要解决此问题,可以执行以下两种操作之一。非此即彼

    现在,有一个更有效的建议。只需使用
    forEach
    和一个可以累积属性的对象,而不是每次()


    这是因为arrow函数在arrow
    =>
    之后等待大括号字符
    {}
    ,但您希望返回大括号对象本身。我建议用括号括住对象,如下所示:

    public renameJson2(json: any): any {
        const result: any = {};
    
        Object.keys(json).forEach((key: string) => {
            const resultKey = this.isUpperCase(key.charAt(1)) ? key.toLowerCase() : this.getFirstLetterToLowerCase(key);
    
            result[resultKey] = this.getTransform(json[key]);
        });
    
        return result;
    }
    

    您是否考虑过对关键点执行
    forEach
    ,并一次一个关键点构建对象,而不是每次迭代都重建一个新对象?第2点无关紧要。TS不在乎是否忽略额外的参数(JS也不在乎)。
    public renameJson2(json: any): any {
        const result: any = {};
    
        Object.keys(json).forEach((key: string) => {
            const resultKey = this.isUpperCase(key.charAt(1)) ? key.toLowerCase() : this.getFirstLetterToLowerCase(key);
    
            result[resultKey] = this.getTransform(json[key]);
        });
    
        return result;
    }
    
    public renameJson2(json: any): any {
        return Object.keys(json).reduce(
          (s, item) => ({
            ...s,
            [this.isUpperCase(item.charAt(1))
              ? item.toLowerCase()
              : this.getFirstLetterToLowerCase(item)]: this.getTransform(json[item])
          }),
    
          {}
        );
      }