在 TypeScript 的类中实现索引器

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

目前可以在 TypeScript 中的类上实现索引器吗?

class MyCollection {
   [name: string]: MyType;       
}

这无法编译。当然,我可以在接口上指定索引器,但我需要这种类型的方法以及索引器,因此接口是不够的。

谢谢。

class typescript indexer
5个回答
42
投票

您无法使用索引器实现类。您可以创建一个接口,但该接口不能由类实现。它可以用纯 JavaScript 实现,您可以在界面上指定函数以及索引器:

class MyType {
    constructor(public someVal: string) {

    }
}

interface MyCollection {   
   [name: string]: MyType;
}

var collection: MyCollection = {};

collection['First'] = new MyType('Val');
collection['Second'] = new MyType('Another');

var a = collection['First'];

alert(a.someVal);

15
投票

对于那些寻找答案的人来说,这是一个老问题:现在可以定义一个索引属性,例如:

let lookup : {[key:string]:AnyType};

密钥的签名必须是字符串或整数,请参阅:

www.typescriptlang.org 上的界面


9
投票

不可能在类中定义索引属性 getter/setter,但您可以使用 Proxy 以类似的方式“模拟”它:

class IndexedPropSample  {
  [name: string | symbol]: any;

  private static indexedHandler: ProxyHandler<IndexedPropSample> = {
    get(target, property) {
      return target[property];
    },
    set(target, property, value): boolean {
        target[property] = value;
        return true;
    }
  };

  constructor() {
      return new Proxy(this, IndexedPropSample.indexedHandler);
  }

  readIndexedProp = (prop: string | symbol): any => {
      return this[prop];
  }

}


var test = new IndexedPropSample();

test["propCustom"] = "valueCustom";

console.log(test["propCustom"]); // "valueCustom"
console.log(test.readIndexedProp("propCustom")); // "valueCustom"
console.log(test instanceof IndexedPropSample); // true
console.log(Object.keys(test)); // ["propCustom", "readIndexedProp"]

你可以在Typescript Playground

尝试一下

2
投票

@Dardino:Thant 帮了很多忙。谢谢。 如果有人还需要通过代理进行函数调用和访问属性,这里是一些基于 Dardinos 的代码。

  private static indexedHandler: ProxyHandler<IndexedPropSample> = {
    get(target, prop) {
      if (typeof prop === "string" && !(typeof target[prop as string])) {
        // Array access
        return target.getItem(prop);
      }
      else if ((typeof prop === "string" && typeof target[prop as string] === "function")) {
        // function call
        return target[prop].bind(target);
      } else if (typeof prop === "string") {
        // property access
        return target[prop];
      }

      return undefined;
    },
    set(target, prop, value): boolean {
      if (typeof prop === "string" && !(typeof target[prop as string])) {
        // Array access
        target.setItem(prop, value);
        return true;
      } else if (typeof prop === "string") {
        // property access
        return target[prop] = value;
      }
      return false;
    }
  };

0
投票

不过,您可以使用静态方法:

class MyCollection {
    [name: string]: string;
    static print(collection: MyCollection) {
        console.log(collection);
    }
}

游乐场

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