假设有一个接口:
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;
答案 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?