[英]How TO: Typescript nested typing A<B<GENERIC>>
Is it possible to have this kind of typing in typescript?是否可以在 typescript 中进行这种键入?
interface Worker<T> {
renderChunk: (projectUrl: string, from: number, to: number) => Promise<T>;
}
interface WorkerPool<W<U>> {
addWorker(worker: W, address: number): void;
getIdleWorker(): W | null;
}
But I also want some type of restriction that checks that W
should be an implementation of Worker
, let's say you have for example an implementation of Worker as follow:但我也想要某种类型的限制来检查W
是否应该是Worker
的一个实现,假设你有一个 Worker 的实现,如下所示:
class RenderWorker implements Worker<string[]> {
renderChunk: (projectUrl: string, from: number, to: number) => Promise<string[]> {
return Promise.resolve(['Foo'])
}
}
The below implementation should be acceptable by typescript: typescript 应该可以接受以下实现:
class RenderWorkerPool implements WorkerPool<RenderWorker> {}
however this one should not be acceptable as string
is not an implementation of Worker
然而,这个不应该被接受,因为string
不是Worker
的实现
class RenderWorkerPool implements WorkerPool<string> {}
Yes, using constrained generic types , you can ensure that W
extends Worker
.是的,使用受约束的泛型类型,您可以确保W
扩展Worker
。
interface WorkerPool<W extends AaWorker<any>> {
addWorker(worker: W, address: number): void;
getIdleWorker(): W | null;
}
Because of the nested generic, if you want to reason about the type of the worker, you'll need to specify that as well:由于嵌套泛型,如果你想推断 worker 的类型,你还需要指定它:
interface WorkerPool<U, W extends AaWorker<U>> {
addWorker(worker: W, address: number): void;
getIdleWorker(): W | null;
}
But, as Bernardo Duarte points out in the comments, you might not need generics for Worker at all.但是,正如Bernardo Duarte在评论中指出的那样,您可能根本不需要 generics 作为 Worker。 Instead, just take any conforming Worker implementation with the right generic type:相反,只需采用具有正确泛型类型的任何符合标准的 Worker 实现:
interface WorkerPool<U> {
addWorker(worker: AaWorker<U>, address: number): void;
getIdleWorker(): AaWorker<U> | null;
}
(I've changed Worker
to AaWorker
above, just so there's no naming conflict between your Worker and the Web Worker built-in objects.) (我已将上面的Worker
更改为AaWorker
,这样您的 Worker 和 Web Worker 内置对象之间就不会发生命名冲突。)
I think you want this:我想你想要这个:
interface WorkerPool<W extends Worker<unknown>> {
addWorker(worker: W, address: number): void;
getIdleWorker(): W | null;
}
W
is constrained by Worker<unknown>
. W
受Worker<unknown>
约束。 So W
is inferred to be a Worker
, and the generic T
of that worker is also inferred as part of that.因此W
被推断为Worker
,并且该工人的通用T
也被推断为其中的一部分。
class RenderWorkerPoolA implements WorkerPool<RenderWorker> {} // fine
class RenderWorkerPoolB implements WorkerPool<string> {} // Type 'string' does not satisfy the constraint 'Worker<unknown>'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.