[英]TypeScript: is it possible to force a generic type in a interface signature that be of the same type of class that implements this interface
I want to force a declared generic in a signature of the interface be of the same type of the class that implements this interface.我想强制接口签名中声明的泛型与实现此接口的 class 类型相同。 Something like the below code:类似于下面的代码:
interface I1<T = typeof this> {
aAnyMethod(): I1<T>;
}
class C1 { }
class C2 implements I1<C1> /* accepts C1 but shouldn't, it should only accept C2 */ {
// ok. It works as it should
aAnyMethod(): C2 {
return new C2;
}
}
class C3 implements I1{
// not accepted. It works as it should
aAnyMethod(): C1 {
return new C1;
}
}
You can give the type parameter a self-referential upper bound.你可以给类型参数一个自引用的上限。 This is a standard solution to this problem, used eg in Java's interface Comparable<T extends Comparable<T>>
.这是该问题的标准解决方案,例如在 Java 的接口Comparable<T extends Comparable<T>>
中使用。
interface MyInterface<T extends MyInterface<T>> {
someMethod(): T;
}
class Works implements MyInterface<Works> {
someMethod() { return new Works(); }
foo() { return 'foo'; }
}
// error: Type 'SomethingElse' does not satisfy the constraint 'MyInterface<SomethingElse>'.
class DoesntWork implements MyInterface<SomethingElse> {
someMethod() { return new SomethingElse(); }
}
Unfortunately, something like this will still work:不幸的是,这样的事情仍然有效:
// No error, because Works extends MyInterface<Works>
class ShouldntWorkButDoes implements MyInterface<Works> {
someMethod() { return new Works(); }
baz() { return 'baz'; }
}
However, this doesn't cause a problem because anywhere you want to accept something implementing MyInterface
, you can require that it implement MyInterface<...>
of itself:但是,这不会导致问题,因为在任何地方你想接受实现MyInterface
的东西,你可以要求它实现MyInterface<...>
自己:
function acceptsMyInterface<T extends MyInterface<T>>(arg: T) {}
// OK
acceptsMyInterface(new Works());
// error: Argument of type 'ShouldntWorkButDoes' is not assignable to parameter of type 'MyInterface<ShouldntWorkButDoes>'.
acceptsMyInterface(new ShouldntWorkButDoes());
So then ShouldntWorkButDoes
only works where it is declared, not where it is used.因此, ShouldntWorkButDoes
仅适用于声明它的地方,而不是使用它的地方。 (Note that for the purpose of this demonstration, I had to add some members foo
and baz
so that Typescript doesn't treat these types as structurally equivalent .) (请注意,出于本演示的目的,我必须添加一些成员foo
和baz
以便 Typescript 不会将这些类型视为结构等效。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.