【问题标题】:Add a new property in a JSON Object在 JSON 对象中添加新属性
【发布时间】:2021-10-03 01:26:25
【问题描述】:

我有一个 Tyescript 项目,其中有一个带有 JSON 对象的类,我想在其中添加一个新属性。

这是我当前的对象:

let files = [    { codCountry: 'CO', fileName: 'CO_SER.csv' },
                 { codCountry: 'CO', fileName: 'CO_INS.csv' },
                 { codCountry: 'CO', fileName: 'CO_BRA.csv' } ];

这就是我想要实现的目标:

let files = [    { codCountry: 'CO', fileName: 'CO_SER.csv', exists: 1, error: 0 },
                 { codCountry: 'CO', fileName: 'CO_INS.csv', exists: 0, error: 0 },
                 { codCountry: 'CO', fileName: 'CO_BRA.csv', exists: 0, error: 1 } ];

这就是我正在做的:

files.push({ exists: 1, error: 0 }, { exists: 0, error: 0 }, { exists: 0, error: 1 });

这是它返回的错误:

无法将“{exists: number; error: number;}”类型的参数分配给“{codCountry: string; fileName: string;}”类型的参数。 对象字面量只能指定已知属性,并且类型'{codCountry: string; 中不存在'exists'。文件名:字符串; } '

【问题讨论】:

    标签: arrays json typescript


    【解决方案1】:

    Typescript 将您的数组类型推断为 {codCountry: string; fileName: string;}[]

    由于此推断类型没有 existserror 属性,并且您尝试推送的对象缺少 codCountryfileName 属性,因此您无法将这些项目推送到该数组中。

    您可以创建一个具有可选属性的类型TFile,并在声明它时使用它显式键入files

    type TFile = {
      codCountry: string;
      fileName: string;
      exists?: number;
      error?: number;
    };
    
    let files: TFile[] = [
      { codCountry: "CO", fileName: "CO_SER.csv" },
      { codCountry: "CO", fileName: "CO_INS.csv" },
      { codCountry: "CO", fileName: "CO_BRA.csv" },
    ];
    
    const extraFields = [
      { exists: 1, error: 0 },
      { exists: 0, error: 0 },
      { exists: 0, error: 1 },
    ];
    
    const newFiles = files.map((file, i) => {
      const {exists, error} = extraFields[i];
      return {
        ...file,
        exists,
        error,
      };
    });
    

    TS Playground

    【讨论】:

    • 这向我添加了另一个元素,我想要在元素中添加这些属性。这就是我所取得的成就:[ { codCountry: 'CO', fileName: 'CO_SER.csv' }, { codCountry: 'CO', fileName: 'CO_INS.csv' }, { codCountry: 'CO', fileName: 'CO_BRA.csv' }, { exists: 1, error: 0 }, { exists: 0, error: 0 }, { exists: 0, error: 1 } ]
    • 虽然这将编译和运行,但它可能不是 OP 真正想要的。据我了解这个问题,他想将existserror 属性添加到数组中已经存在的项目中......
    【解决方案2】:

    您正在向“文件”数组添加新元素,而不是向数组中的对象添加新属性。

    你可以这样做:

    files.forEach(object => {
        object.error = 1 //or 0
        object.exists = 1 //or 0
    })
    

    【讨论】:

    • 这将在纯 JS 中工作。但是由于 TS 确保编译时类型安全,这将不起作用。此外,数组中的不同元素可能会得到不同的值(尤其是当前给push的值)
    【解决方案3】:

    有两个问题:

    1. 由于您没有为数组项明确定义类型,因此打字稿会从现有项中推断出类型。因此,您的文件具有以下类型

      let files: {codCountry: string, fileName: string }[] = ...

      要允许向对象添加其他属性,您必须在类型中定义它们。

    2. 您不能使用Array.push 向数组中的现有项目添加新属性。 push 会将新项目添加到数组的末尾。如果要为现有项添加属性,则必须遍历数组并分别为每个项添加属性。

    所以让我们首先定义一个合适的类型,它将existserror 作为可选属性。

    let files: {codCountry: string, fileName: string, exists?: number, error?: number }[] = [
        { codCountry: 'CO', fileName: 'CO_SER.csv' },
        { codCountry: 'CO', fileName: 'CO_INS.csv' },
        { codCountry: 'CO', fileName: 'CO_BRA.csv' }]
    
    

    然后我们定义新数据

    let additional = [{ exists: 1, error: 0 }, { exists: 0, error: 0 }, { exists: 0, error: 1 }];
    

    最后,检查数组并添加新属性:

    for (let i = 0; i < files.length; i++) {
      files[i].exists = additional[i].exists;
      files[i].error = additional[i].error;
    }
    

    您也可以使用Array.forEach() 来遍历数组

    files.forEach((file, i) => {
      file.exists = additional[i].exists;
      file.error = additional[i].error;
    })
    

    【讨论】:

      猜你喜欢
      • 2012-05-28
      • 2017-02-10
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      • 2016-12-30
      • 1970-01-01
      • 2018-12-05
      • 1970-01-01
      相关资源
      最近更新 更多