Typescript:通过在数组中定义的键访问嵌套对象的值

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

Typescript: access nested object values through keys defined in array

问题

I was wondering how I could make the error on this LINK disappear.

tl;dr 我有一个类型,既包含嵌套属性(对象),又包含常规属性(字符串、布尔等)。我试图检查嵌套值是否为非空字符串。考虑到有很多这样的属性,我正在使用一个包含应该被检查的类型键的字符串数组。我正在寻找一个解决方案,不会强迫我将已定义的类型拆分为单独的类型,然后再合并它们。

谢谢你提前的帮助。

EDIT: 添加了代码和更新的TypeScript Playground链接

type MyRecord = {
    id: string;
    value: string;
}
type MyType = {
    a: MyRecord;
    b: MyRecord;
    c: string,
    d: string,
}

const validate = (r: MyType) => {
    const keys = ["a", "b"];
    for (const key of keys) {
        if (r[key as keyof MyType].value !== "") {
            return false;
        }
    }
    return true;
}

抛出的错误:

Property 'value' does not exist on type 'string | MyRecord'. Did you mean 'valueOf'?
  Property 'value' does not exist on type 'string'.

<details>
<summary>英文:</summary>

I was wondering how I could make the error on this [LINK][1] disappear.

tl;dr I have a type that has both nested properties(object) and regular ones(string,boolean etc.). I am trying to check if nested values are non empty strings. But considering there are many of them I am using a string array with the type keys that should be checked. I am looking for a solution that will not force me to split the defined type into separate types and then just merging them together. 

Thanks in advance

EDIT: ADDED CODE AND UPDATED TYPESCRIPT PLAYGROUND LINK

type MyRecord={
id:string;
value:string;
}
type MyType={
a:MyRecord;
b:MyRecord;
c:string,
d:string,
}

const validate = (r:MyType)=>{
const keys=["a","b"];
for (const key of keys){
if(r[key as keyof MyType].value!==""){
return false
}
}
return true
}


Thrown error:

Property 'value' does not exist on type 'string | MyRecord'. Did you mean 'valueOf'?
Property 'value' does not exist on type 'string'.



  [1]: https://www.typescriptlang.org/play?#code/C4TwDgpgBAsiBKEDGB7ATgEwLwG8BQUhUAlhgFwDOwaxAdgOYDcBRAbgIYA2ArhJdXSZ4AvnlCRYIACrgIuFoXZk4iVJmZEoAI2UJk6DBqJJ+NBgBoFUclTP1LovKlpUoHTqXbBoWKAAo0XRlIAEosAD58TWdXAGsIEAosAG0AInZU81StVIBdI0IAM3R-GOAoeJAoFEKKhIoQqM0iYkKA5Mqodgo6kBrJYIhcgDp3XgBCLCxU1Ma8K01RRas0CGBuNFooal4RIA

</details>


# 答案1
**得分**: 2

```plaintext
我遇到了这个问题。并且只找到了一种解决方法

```typescript
type MyRecord = {
    id:string;
    value:string;
} & string

type StrObj = {
    a: MyRecord,
    b: MyRecord,
    c: MyRecord,
    d: MyRecord,
}

type A = keyof StrObj


const validate = (r:StrObj)=>{
    const keys: Array<A> = ["a" ,"b"]
    for (const key of keys) {
        if (r[key].value) {

        }
    }
    return true
}

在我看来,这似乎不是最好的方式... 但它有效。最近我尝试寻找其他解决方案,但似乎没有其他的解决方法


<details>
<summary>英文:</summary>

I had this problem. And found only one way to resolve this

type MyRecord = {
id:string;
value:string;
} & string

type StrObj = {
a: MyRecord,
b: MyRecord,
c: MyRecord,
d: MyRecord,
}

type A = keyof StrObj

const validate = (r:StrObj)=>{
const keys: Array<A> = ["a" ,"b"]
for (const key of keys) {
if (r[key].value) {

    }
}
return true

}


In my opinion looks like not the best way... But works.
Recently I tried to find other solution, but looks like there is no other solution

</details>



# 答案2
**得分**: 0

替代将 `keys` 定义为 `string[]`,你可以添加 `as const` 以使类型变为 `readonly ["a", "b"]`

```javascript
const validate = (r: MyType) => {
    const keys = ["a", "b"] as const;
    for (const key of keys) {
        if (r[key].value !== "") {

        }
    }
    return true;
}
英文:

Instead of having keys as a string[] you could add a as const to make the type readonly [&quot;a&quot;, &quot;b&quot;]

const validate = (r:MyType)=&gt;{
    const keys=[&quot;a&quot;,&quot;b&quot;] as const;
    for (const key of keys){
        if(r[key].value!==&quot;&quot;){

        }
    }
    return true
}

huangapple
  • 本文由 发表于 2023年2月16日 01:55:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75463703.html
匿名

发表评论

匿名网友

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

确定