打字稿:具有名称获取器/设置器属性的类

时间:2018-11-17 16:26:34

标签: typescript

假设有一个接口:

interface ServiceDataIf {
  somethingToDo(): void;
  mayBeAdd(arg: any): void;
  mayBeGet(name: string): any;
  readonly someVal: string;
  anotherVal: string;
  [name: string]: any;
}

如何在类中实现此接口:

class ServiceDataImpl1 implements ServiceDataIf {
  // easy with properties
  get someVal(): string {
    const result = /* somehow get it */;
    return result;
  }

  constructor() {}

  set anotherVal(v: string): void {
    // remember somewhere v
  }

  // plain methods easy as well
  somethingToDo(): void { /* do something */ }
  mayBeAdd(arg: any): void { /* do another something */ }
  mayBeGet(name: string): any {
    const result = /* somehow get it */;
    return result;
  }

  // How to implement this? [name: string]: any;
}

方法和属性都可以,是否可以用类来实现by key访问器?为了澄清,[name: string]: any访问器是否可以像获取/设置属性一样被实现为类方法?

以便可以这样使用:

const myImpl = new ServiceDataImpl1();

// read
const val1 = myImpl['something'];
// write
myImpl['something'] = 256;

2 个答案:

答案 0 :(得分:1)

最后,这样的界面作为要搜索的关键字,称为indexer。这样便可以获得足够的信息。例如,根据以下讨论,似乎不可能在Typescript中开箱即用地实现这样的接口:

因为它与JavaScript引起歧义,所以被禁止。

但是,ES2015中有Proxy,尽管不是很容易,但它可以实现所需的功能。以下说明了方法,但没有完整说明。

interface SomeIf {
  [name: string]: any;
}

class SomeImpl implements SomeIf {
  constructor() {
    return new Proxy(this, {
      get: (obj: any, key: string | number | symbol, receiver: any) => {
        console.log('get', key, obj, receiver);
        return key === 'abc' ? 53 : key in obj ? obj[key] : undefined;
      },
      set: (obj: any, key: string | number | symbol, value: any, receiver: any) => {
        console.log('set', key, value, obj, receiver);
        return true;
      }
    });
  }
}

const impl1 = new SomeImpl();
impl1['abc'] = 123;
console.log(`impl1['abc']`, impl1['abc']);

请注意,如果需要在浏览器中使用,较旧的浏览器将不支持Proxy

答案 1 :(得分:0)

如果我现在正确理解,您希望将属性动态添加到类中。然后,如果您尝试访问未添加或不在界面中的内容,则想引发编译错误。

此行

export

基本上允许存在任何类型的ANY属性。

TypeScript无法在运行时中推断类型。因此,按照接口中的定义,它将允许存在任何属性。即使未将其添加到某处。

TypeScript只能进行编译时检查。

啊。而且您不能在界面中强制执行getter / setter。 如此处所述:Is it possible to use getters/setters in interface definition?