使用启用严格函数类型的TypeScript,我试图表示一个函数create
,它接受一个本身带有IService
参数的新对象:
interface IService { }
interface Constructible<T> {
new(service: IService): T;
}
declare function create<T>(ctor: Constructible<T>): void;
然后,我想使用一个在构造函数中使用更特定版本的create
的Manager
类来调用IService
。
interface RequestService extends IService {
makeRequest(): void;
}
class Manager {
constructor(requestService: RequestService) { }
}
create<Manager>(Manager);
这在启用严格的函数类型时确实有效。调用create
的错误是:
Argument of type 'typeof Manager' is not assignable to parameter of type 'Constructible<Manager>'.
Types of parameters 'requestService' and 'service' are incompatible.
Property 'makeRequest' is missing in type 'IService' but required in type 'RequestService'.
为什么会发生此错误,并且我可以在不使用强制转换和不内联类型的情况下表示此模式?
我知道唯一可行的解决方法是内联Constructible
并使用extends
。
declare function create<T, S extends IService>(ctor: { new(service: S): T; }): void;
不幸的是,如果我对提取的接口进行同样的尝试,它将无法工作:
interface Constructible<T> {
new<S extends IService>(service: S): T;
}
发布于 2019-10-28 22:41:24
我认为你的解决办法基本上是可行的。有了提供的信息(正如jcalz提到的那样,更多的信息可能会产生来自我们的更好的建议),我建议将S
放在Constructible
类型上,而不是构造函数签名。从我在这个例子中可以看到,实现类本身并不是泛型的(即。它不能接受调用者想要的任何S
,它需要一个由类声明确定的特定S
)
interface IService { }
interface Constructible<T, S extends IService> {
new(service: S): T;
}
declare function create<T, S extends IService>(ctor: Constructible<T, S>, service: S): void;
interface RequestService extends IService {
makeRequest(): void;
}
class Manager {
constructor(requestService: RequestService) { }
}
create(Manager, {
makeRequest() { }
});
我还向create
函数添加了一个服务类型的参数。不确定如何确保服务参数在实际代码中正确,但这似乎是调用方需要知道的东西,而不是实现。
https://stackoverflow.com/questions/58600169
复制