访问 Typescript 中嵌套对象的属性

问题描述 投票:0回答:1

我有一个父对象和子对象,如下所示:

export interface ChildObject {
  [key: string]: string | number | boolean;
  id: number;
  title: string;
  quantity: number;
  rate: number;
  enabled: boolean;
}

export interface ParentObject {
  [key: string]: string | number | ChildObject;
  id: number;
  name: string;
  quantity: number;
  rate: number, 
  children1: ChildObject,
  children2: ChildObject, 
  children3: ChildObject
}

我(天真地)尝试访问子对象的参数:

    parent: {
      'name': 'parentName',
      'quantity': 1,
      'rate': 100,
      'children1': {}
    } as ParentObject,
    child: {
      'title': 'childName',
      'quantity': 1
    } as ChildObject

    modifyChildValues(index:string, quantity: number, direction: string) {
      this.parent[index]['quantity'] += quantity;
    },

理想情况下可以这样调用:

index = 'children1';
quantity = 1;
direction = 'increase';

modifyChildValues(index, quantity, direction)

这应该会导致

parent.children1.quantity
的值增加 1。

我尝试输入各种参数但没有成功。如何通过父对象动态访问和修改子对象的属性,如图所示?

以下作品:

if (index == 'children1'){
        this.parent[index].quantity += quantity;
}

但是,如果我尝试不使用 if 子句,我会在 VSCode 中收到错误:

Property 'quantity' does not exist on type 'string | number | { [x: string]: string | number | boolean; id: number; title: string; quantity: number; rate: number; enabled: boolean; }'.

我尝试了 stackoverflow 上找到的各种解决方案,但没有取得太大成功。错误消息示例包括:

Element implicitly has an 'any' type because expression of type '"quantity"' can't be used to index type 'string | number | { [x: string]: string | number | boolean; id: number; title: string; quantity: number; rate: number; enabled: boolean; }'

Property 'quantity' does not exist on type 'string | number | { [x: string]: string | number | boolean; id: number; title: string; quantity: number; rate: number; enabled: boolean; }'.
typescript
1个回答
0
投票

您可以使

index
参数更严格

modifyChildValues(index: 'children1' | 'children2' | 'children3', quantity: number, direction: string) {
  this.parent[index]['quantity'] += quantity;
}

这意味着

modifyChildValues
只会接受这些字符串作为
index
,并且它知道使用这些值来索引
parent
将始终导致
ChildObject

但是,使用此解决方案时,这三个字符串是唯一可接受的参数。如果您需要支持使用任何字符串而不仅仅是已知键调用该函数,那么您可以在函数内部添加一个检查,以确保您正在访问

ChildObject

modifyChildValues(index: string, quantity: number, direction: string) {
  if (typeof this.parent[index] === 'object') {
    this.parent[index]['quantity'] += quantity;
  }
}

定义

[key: string]: string | number | ChildObject;
意味着字符串键的属性可以是
string
number
ChildObject
。通过添加
typeof
检查,您可以排除
string
number
的可能性,并确保该属性是
ChildObject

© www.soinside.com 2019 - 2024. All rights reserved.