在TypeScript的类中实现索引器

t5zmwmid  于 2023-03-04  发布在  TypeScript
关注(0)|答案(4)|浏览(113)

当前是否可以在TypeScript中的类上实现索引器?

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

当然,我可以在一个接口上指定一个索引器,但是我需要这个类型上的方法以及索引器,所以一个接口是不够的。
谢谢。

798qvoo8

798qvoo81#

不能使用索引器实现类。可以创建接口,但该接口不能由类实现。它可以用纯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);
gkl3eglg

gkl3eglg2#

这是一个老问题,对于那些寻找答案:现在可以定义一个索引属性,如下所示:
let lookup : {[key:string]:AnyType};
密钥的签名必须是字符串或整数,请参阅:
Interfaces on www.typescriptlang.org

xtfmy6hx

xtfmy6hx3#

不可能在类中定义索引属性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"]

你可以在打字本Playground试试

zy1mlcev

zy1mlcev4#

@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;
    }
  };

相关问题