我想动态添加接口中定义的方法。我以为索引签名将是必经之路,但可悲的是,并非所有方法都适合同一签名。我的目标是保留所有类型信息。
基本代码,由于尚未实现所有方法,因此当前无法编译。当我添加Partial
时,代码可以编译,但是我似乎丢失了类型信息。
import anotherLib from "anotherLib";
interface IALotOfMethods<T> {
methodA(): T;
methodB(opts: MyOpts): T;
...
}
interface IMyClass<T> extends IALotOfMethods<T> {
getName(): string;
getSomething(): number;
}
class MyClass implements IMyClass<MyClass> {
results: any[] = [];
getName(): string {
return "A Name";
}
getSomething(): number {
return 0;
}
}
const aLotOfMethodsList = ['methodA', 'methodB', ...];
aLotOfMethodsList.forEach(funcName => {
MyClass.prototype[funcName] = function(opts: any) {
this.results.push(anotherLib[funcName](opts));
return this;
}
})
const myObj = new MyClass();
myObj.methodA(); // methodA should be available/autosuggested
这可能吗?即使它们基本上看起来都一样,我是否需要手动实现所有方法?我需要放弃类型信息吗?
谢谢
答案 0 :(得分:1)
here也使用的一种解决方案是将类和接口与可选属性合并。
interface Component {
optionalMethod?(l: GetLocalization): void;
}
abstract class Component {
public abstract mustImplement(): void;
}
class Post extends Component {
public mustImplement(): void {}
}
在您的情况下:Stackblitz
自动完成有效,但是您可能会收到“无法调用未定义的方法”警告,因此您必须确定自己在做什么
编辑:如果不进行双重合并,甚至更好
import anotherLib from "anotherLib";
abstract class Component<T> {
methodA?(): T;
methodB?(opts: string): T;
public abstract mustImplement(): void;
}
class Post extends Component<string> {
public mustImplement(): void {
}
}
const aLotOfMethodsList = ['methodA', 'methodB'];
aLotOfMethodsList.forEach(funcName => {
(Post as any).prototype[funcName] = function(opts: any) {
this.results.push(anotherLib[funcName](opts));
return this;
}
})
const myObj = new Post();
myObj.methodA(); // autocomplete