如何定义支持私有/受保护构造函数的可构造类型?
解决方案
可以通过调整类型约束的方式解决,不需要修改构造函数的可见性。核心思路是不再强制要求构造函数的可见性,而是通过类的原型来约束其实现目标接口,具体做法如下:
修改类型定义
将原来要求public无参构造函数的InterfaceContructor类型,改为约束类的原型符合Interface:
interface Interface { get FooVal(): any; } // 新的类型约束:仅要求类的原型实现Interface,不限制构造函数 type InterfaceConstructor = { prototype: Interface }; function bar<T extends InterfaceConstructor>(cls: T) { }
调整后的完整代码
interface Interface { get FooVal(): any; } type InterfaceConstructor = { prototype: Interface }; function bar<T extends InterfaceConstructor>(cls: T) { } class UserClass implements Interface { private readonly foo: string; get FooVal() { return this.foo; } protected constructor(validated_string: string) { this.foo = validated_string; } // 静态工厂方法保持不变 static create(validatedString: string): UserClass { return new UserClass(validatedString); } } bar(UserClass); // 类型检查通过
原理说明
原来的{ new(): Interface }类型强制要求构造函数是public且无参数,但UserClass的构造函数是protected且带参数,导致类型不兼容。而修改后的{ prototype: Interface }仅验证类的实例实现了Interface(通过原型链判断),完全不关心构造函数的可见性或参数列表,完美适配私有/受保护构造函数的场景。
如果不需要单独定义InterfaceConstructor类型,也可以直接在函数泛型约束中写:
function bar<T extends { prototype: Interface }>(cls: T) { }
内容的提问来源于stack exchange,提问作者Labrasones
相关产品推荐
相关产品推荐

