打字稿索引签名访问者

时间:2017-06-11 00:56:56

标签: javascript typescript accessor index-signature

我希望我的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 的回答和评论对话后更新:

使用它的角度分量是:

<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提供关于解决我整体问题的建议。

但是我非常感谢知道是否有办法获取打字稿索引签名值?

1 个答案:

答案 0 :(得分: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
    }
};