简体   繁体   English

TypeScript:是否可以强制接口签名中的泛型类型与实现此接口的 class 类型相同

[英]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 .) (请注意,出于本演示的目的,我必须添加一些成员foobaz以便 Typescript 不会将这些类型视为结构等效。)

Playground Link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 TypeScript:实现某个接口或方法的 class 的类型 - TypeScript: type of class that implements a certain interface or method 我可以在一个类中定义一个特定的类类型,该类在打字稿中实现了一个具有泛型类型的接口吗? - Can I define a specific class type in a class that implements an interface with a generic type in typescript? 接口字段应具有实现该接口的类的类型-typescript - Interface field should have type of the class that implements that interface - typescript 打字稿:通用类型使用Extends关键字而不是带有接口的Implements - Typescript: Generic Type uses Extends keyword instead of Implements with interface TypeScript 接口/类型 Function 签名 - TypeScript Interface / Type for Function Signature Typescript - 使函数返回类型成为接口实现的类 - Typescript - Make the function return type the class that an interface implements TypeScript Class 使用联合类型字段实现接口导致错误 (2322) - TypeScript Class Implements Interface with Union Type Field results in Error (2322) 打字稿:通用接口,接口函数和类类型参数 - Typescript: generic interface, interface functions and class type parameters 具有接口类类型的泛型 - Generic with interface class type TypeScript&React - 组件实现接口 - 用作类型? - TypeScript & React - Component implements interface - use as a type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM