typescript 如何定义接受私有/受保护构造函数的可构造类型

i7uq4tfw  于 2023-03-09  发布在  TypeScript
关注(0)|答案(1)|浏览(124)

我试图实现一个函数,它接受一个泛型类/构造函数作为参数,这个泛型类/构造函数被约束到一个特定接口的实现者。我能够通过一个“constructable”类型(下面的示例中的InterfaceConstructor)来实现这一点。
然而,我遇到了一个复杂的问题,我需要使用这个函数的一个类类型需要一个私有/受保护的构造函数。(即传递给它的构造函数的参数必须来自一个工厂方法,该方法已经预先验证了它们,并且不应该使用最终用户的new进行示例化)。
不幸的是,由于公共/受保护的构造函数类型问题,这会导致可构造类型的匹配时间更长。这个问题可以在不改变构造函数可见性的情况下解决吗?

interface Interface { get FooVal(): any; }
type InterfaceContructor = { new(): Interface }
function bar<T extends InterfaceContructor>( bar: T ) { }

class UserClass implements Interface {
    private readonly foo: string;
    get FooVal() { return this.foo; }
    protected constructor( validated_string: string )
    {
        this.foo = validated_string;
    }
    // Static factory methods are provided to instantiate the class for end users of the type
    // ...
}

bar( UserClass ); // Argument of type 'typeof UserClass' is not assignable to parameter of type 'InterfaceContructor'. Cannot assign a 'protected' constructor type to a 'public' constructor type.
qni6mghb

qni6mghb1#

如果构造函数是私有的或受保护的,那么bar无论如何都不能调用它,因此将其作为bar所需类型的一部分没有多大意义。
因此,如果bar打算调用您提到的这些"静态工厂方法",那么这些方法需要成为bar接受的类型的一部分。
例如:

interface Interface { get FooVal(): any; }
type InterfaceContructor = { makeInstance(): Interface }

function bar<T extends InterfaceContructor>( bar: T ) {
  const instance = bar.makeInstance()
  console.log(instance.FooVal) // fine
}

你只需要给它一个类构造函数,它有一个静态接口来匹配它。

class UserClass implements Interface {
  private readonly foo: string;
  get FooVal() { return this.foo; }
  
  protected constructor( validated_string: string ) {
      this.foo = validated_string;
  }
  
  static makeInstance() {
    return new this('Hello')
  }
}

bar( UserClass ); // fine

见Playground

相关问题