【问题标题】:typescript index signature accessors打字稿索引签名访问器
【发布时间】:2017-06-11 00:56:56
【问题描述】:

我希望我的 javascript 数据是这样的:

"dogs": {
    "ada": {
        age: 7,
        breed: poodle
    },
    "levin": {
        age: 5,
        breed: shitzu
    },
    ...
}

其中名称是对象键。我有这个打字稿类:

export class Dog {
  [dogName: string]: DogDetails;
}

我可以看到我可以封装方法来创建访问器的唯一方法是将这些静态方法添加到Dog

  public static getDogName(dog: Dog): string {
    return Object.keys(dog).toString();
  }

  public static getDogDetails(dog: Dog): DogDetails {
    return dog[Dog.getDogName(dog)];
  }

这太可怕了。一个原因是需要静态访问:

Dog.getDogName(dog)  // this is how it must be done

这似乎与应该如何编写相反,应该是:

dog.getName();  // this unfortunately can't be done

如果有办法访问索引签名值,情况会好很多。但是我找不到任何方法来实现这一点。有没有办法或者有更好的方法来编写这个类?

请注意,这对于使用索引签名的类是不可能的:

public getName(): string {   // this won't work
    Object.keys(this).toString();
}

既然它抱怨Property 'getName' of type '() => string' is not assignable to string index type 'DogDetails'


@amiramw 和 cmets 对话回答后更新:

使用它的角度分量是:

<ion-list *ngFor="let dog of dogs">
    <ion-item>
      <ion-avatar item-start>
        <img src="assets/img/dog.jpg"/>
      </ion-avatar>
      <h4>{{Dog.getName(dog)}}</h4>
      <p>{{Dog.getDogDetails(dog).breed}}</p>
    </ion-item>
  </ion-list>

在反馈之后,我似乎需要写:

<ion-list *ngFor="let dogName of getDogNames()">
    <ion-item>
      <ion-avatar item-start>
        <img src="assets/img/dog.jpg"/>
      </ion-avatar>
      <h4>{{dogName}}</h4>
      <p>{{getDogDetails(dogName).breed}}</p>
    </ion-item>
  </ion-list>

getDogNames() 在哪里:

  public getDogNames(): string[] {
    if (this.dogs) {
      return Object.keys(this.dogs);
    } else {
      return new Array<string>();
    }
  }

getDogDetails() 是:

  public getDogDetails(name: string): DogDetails {
    return this.dogs[name];
  }

这很有效,但不是我想要的。对于解决我的整体问题的建议,我将给予 @amiramw 赞誉。

但是,如果有办法获得打字稿索引签名值,我将不胜感激??

【问题讨论】:

    标签: javascript typescript accessor index-signature


    【解决方案1】:

    您可以为每只狗的数据创建一个接口,并定义一个从字符串到该接口的映射。接口可以命名(以供重用)或匿名:

    enum Breed {
        poodle,
        shitzu
    }
    let dogs : { [key:string]: {age: number, breed: Breed} } = {
        "ada": {
            age: 7,
            breed: Breed.poodle
        },
        "levin": {
            age: 5,
            breed: Breed.shitzu
        }
    };
    

    【讨论】:

    • 这个名字是怎么来的?例如。 “阿达”
    • 您可以通过调用Object.keys(dogs) 获取狗的名单,然后您有名字,您可以通过doing dogs[dogName] 访问每条狗的数据。其他选择是将狗列表维护在一个数组中,并将name 属性添加到接口。
    • 好的,我明白你的方法了。我认为您的打字稿代码与我所拥有的本质上没有任何不同,这只是您访问数据的方法。这可能是我必须这样做的方式,但这与我认为应该这样做的方式相反,并且与教科书的案例不同。我将更新我的问题以使用用于遍历此数据的角码进行限定。感谢您的努力。
    猜你喜欢
    • 1970-01-01
    • 2019-11-14
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2018-12-15
    • 2021-05-20
    • 2019-09-21
    相关资源
    最近更新 更多