我有以下接口:
interface IFactory<T> extends Function {
(...args: any[]): (((...args: any[]) => T)|T);
}
以下代码片段会导致错误:
ts]键入 '((...参数: 任意[]) => IKatana) |IKatana'不能分配给类型'IKatana'。键入"(...args: any[]) => IKatana' 不能分配给类型 'IKatana'。类型"(...args: any[]) => IKatana'. (财产)NinjaWithUserDefinedFactory._katana:伊卡塔纳
@injectable()
class NinjaWithUserDefinedFactory implements INinja {
private _katana: IKatana;
private _shuriken: IShuriken;
public constructor(
@inject("IFactory<IKatana>") katanaFactory: IFactory<IKatana>,
@inject("IShuriken") shuriken: IShuriken
) {
this._katana = katanaFactory(); // error!
this._shuriken = shuriken;
}
public fight() { return this._katana.hit(); };
public sneak() { return this._shuriken.throw(); };
}
有时,可以使用配置多次调用工厂。这也会导致问题:
无法调用类型缺少调用签名的表达式。
class Engine {
constructor(type: string, cc: number) {}
}
let engineFactory: IFactory<Engine> = (type: string) => (cc: number) => {
return new Engine(type, cc);
};
let dieselEngine = engineFactory("diesel");
let dieselEngine300cc = dieselEngine(300); // error!
let dieselEngine320cc = dieselEngine(320); // error!
关于如何克服这个问题的任何想法?
更新
打字稿团队正在研究可变参数,这将解决这个问题。
在以下签名中,您有:
interface IFactory<T> extends Function {
(...args: any[]): (((...args: any[]) => T)|T);
}
更简单的版本是:
interface IFactory<T> {
(...args: any[]): (IFactory<T>|T);
}
你基本上是说调用IFactory
的实例可以给你另一个工厂或T
。
基于此,如果dieselEngine
是一个IFactory
则不能保证调用它会给编译器提供T
或其他IFactory
。因此,使用 dieselEngine(foo)
的结果作为函数是一个错误:
engineFactory("diesel")(300); // Error
修复
从上面的分析中应该可以清楚地看出,您需要预先指定呼叫次数。您可以将其简化为 2 调用工厂:
interface IFactory<T,C> {
(type:string): (configuration:C) => T;
}
class Engine {
constructor(type: string, cc: number) {}
}
let engineFactory: IFactory<Engine,number> = (type: string) => (cc: number) => {
return new Engine(type, cc);
};
let dieselEngine = engineFactory("diesel");
let dieselEngine300cc = dieselEngine(300); // Okay!
let dieselEngine320cc = dieselEngine(320); // Okay!