Add key-value to nested json error – Element implicitly has an 'any'

huangapple go评论77阅读模式
英文:

Add key-value to nested json error - Element implicitly has an 'any'

问题

以下是您要翻译的内容:

我有一个嵌套的JSON如下所示由于它是某个包的一部分我无法修改它

    const myjson = {
        properties: {
            'firstname':'david'
        },
        class: 'primary'
    }

我想要向`properties`添加另一个键值使其看起来像

    const myjson = {
        properties: {
            'firstname':'david',
            'lastname' :'watson'
        },
        class: 'primary'
    }


所以我使用了以下方法

    myjson.properties['lastname'] = 'watson';

这会导致错误

    Element implicitly has an 'any' type because expression of type '"lastname"' can't be used to index type '{ firstname: string; }'.
      Property 'lastname' does not exist on type '{ firstname: string; }'.(7053)

我认为我必须使用`as keyof typeof`类似于以下错误语法并且不能解决错误

    myjson.properties['lastname' as typeof keyof myjson.properties] = 'watson';

带有错误的可运行代码可以在此处查看https://www.typescriptlang.org/play?#code/MYewdgzgLgBAtgTwFYXDAvDA3gKBvmABwCcRCBTYqAS3IgC5s8CWByAM2uOjAEM5yreqwAmvAG7URrZvgC+AGlkxgAG14QGMViWpxexBDLk5EKcADoSZSjToBtVup79BMDTCgIKIdjADW5Ai+8MioYFakFFS0EAC6GNoA7rxQ4awA3DigkCCq5BaqIADmABRm4QCUGUA

**编辑#1** 在上述语句中我在`typeof keyof`的顺序中犯了一个小错误现在错误已经消失了正确的语句是

    myjson.properties['lastname' as keyof typeof myjson.properties] = 'watson';

已更正的代码在此处https://www.typescriptlang.org/play?ssl=7&ssc=76&pln=7&pc=1#code/MYewdgzgLgBAtgTwFYXDAvDA3gKBvmABwCcRCBTYqAS3IgC5s8CWByAM2uOjAEM5yreqwAmvAG7URrZvgC+AGlkxgAG14QGMViWpxexBDLk5EKcADoSZSjToBtVup79BMDTADW5BCHYwoBAo-eGRUMCtSCipaCABdDG0Ad14ocNYAbhxQSBBVcgtVEABzAAozcIBKDKA

**编辑#2** 找到了另一种方法来完成此操作而无需出现错误

    Object.assign(myjson.properties, {'lastname': 'watson'});
英文:

I have a nested json like so, which I cannot modify as it is part of some package

const myjson = {
properties: {
'firstname':'david'
},
class: 'primary'
}

I want to add another key value to properties, so that it looks like

const myjson = {
properties: {
'firstname':'david',
'lastname' :'watson'
},
class: 'primary'
}

So I used the following

myjson.properties['lastname'] = 'watson';

This gives the error

Element implicitly has an 'any' type because expression of type '"lastname"' can't be used to index type '{ firstname: string; }'.
Property 'lastname' does not exist on type '{ firstname: string; }'.(7053)

I think I have to use as keyof typeof something like below which is wrong syntax and doesn't fix the error

myjson.properties['lastname' as typeof keyof myjson.properties] = 'watson';

Runnable code with the error can be seen here https://www.typescriptlang.org/play?#code/MYewdgzgLgBAtgTwFYXDAvDA3gKBvmABwCcRCBTYqAS3IgC5s8CWByAM2uOjAEM5yreqwAmvAG7URrZvgC+AGlkxgAG14QGMViWpxexBDLk5EKcADoSZSjToBtVup79BMDTCgIKIdjADW5Ai+8MioYFakFFS0EAC6GNoA7rxQ4awA3DigkCCq5BaqIADmABRm4QCUGUA

Edit#1: I made a small error in the order of typeof keyof in the above statement. Now the error is gone. The correct statement is

myjson.properties['lastname' as keyof typeof myjson.properties] = 'watson';

Corrected code is here https://www.typescriptlang.org/play?ssl=7&ssc=76&pln=7&pc=1#code/MYewdgzgLgBAtgTwFYXDAvDA3gKBvmABwCcRCBTYqAS3IgC5s8CWByAM2uOjAEM5yreqwAmvAG7URrZvgC+AGlkxgAG14QGMViWpxexBDLk5EKcADoSZSjToBtVup79BMDTADW5BCHYwoBAo-eGRUMCtSCipaCABdDG0Ad14ocNYAbhxQSBBVcgtVEABzAAozcIBKDKA

Edit#2: Found one more way to do this without the error

Object.assign(myjson.properties, {'lastname': 'watson'});

答案1

得分: 2

The inferred type of myjson is:

{
properties: {
firstname: string;
};
class: string;
}

你不能向这个类型添加新属性 - 你需要让 TypeScript 编译器知道 properties 可以接受额外的键。你需要为 myjson 添加一个显式类型。

选项 1: 索引签名

如果你有:

  • 任意属性名称
  • 所有属性都具有相同的类型

使用索引签名

interface MyData {
properties: {
[key: string]: string
},
class: string
}
const myjson: MyData = {
properties: {
'firstname': 'david'
},
class: 'primary'
}
myjson.properties.lastname = 'watson';

选项 2: 可选属性

如果你有:

  • 一些明确定义的属性名称
  • 可能具有不同类型

使用可选属性:

interface MyData {
properties: {
firstname?: string,
lastname?: string,
age?: number
},
class: string
}
const myjson: MyData = {
properties: {
'firstname': 'david'
},
class: 'primary'
}
myjson.properties.lastname = 'watson';

选项 3: 创建新对象

const myjson: MyData = {
properties: {
'firstname': 'david'
},
class: 'primary'
}
const newJson = {
...myjson,
properties: {
...myjson.properties,
lastname: 'watson'
}
}
英文:

The inferred type of myjson is

{
properties: {
firstname: string;
};
class: string;
}

You cannot add new properties to this type - you need to let TS compiler know that properties can accept additional keys.
You need to add an explicit type to myjson

Option 1: Index signature

Use Index signature if you have:

  • arbitrary property names
  • all sharing same type
interface MyData {
properties: {
[key: string]: string
},
class: string
}
const myjson: MyData = {
properties: {
'firstname':'david'
},
class: 'primary'
}
myjson.properties.lastname = 'watson';

Option 2: optional properties

Use optional properties if you have:

  • a few well-defined property names
  • possibly with different types
interface MyData {
properties: {
firstname?: string,
lastname?: string,
age?: number
},
class: string
}
const myjson: MyData = {
properties: {
'firstname':'david'
},
class: 'primary'
}
myjson.properties.lastname = 'watson';

Option 3: create new object

const myjson: MyData = {
properties: {
'firstname':'david'
},
class: 'primary'
}
const newJson = {
...myjson,
properties: {
...myjson.properties,
lastname: 'watson'
}
}

huangapple
  • 本文由 发表于 2023年5月18日 01:38:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76274805.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定