英文:
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 ["a", "b"]
const validate = (r:MyType)=>{
const keys=["a","b"] as const;
for (const key of keys){
if(r[key].value!==""){
}
}
return true
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论