如何定义仅接受具体(非抽象)类型的TypeScript泛型类型?
解决抽象基类作为自定义元素注册时的类型错误
问题背景
当将自定义元素的基类Base标记为abstract后,原有的静态注册方法出现类型错误:
Argument of type 'T' is not assignable to parameter of type 'CustomElementConstructor'. Type 'typeof Base' is not assignable to type 'CustomElementConstructor'. Cannot assign an abstract constructor type to a non-abstract constructor type.
这是因为customElements.define要求传入的构造函数必须是可实例化的具体类型,而原泛型约束T extends typeof Base允许抽象构造函数传入。
解决方案
调整register方法的泛型约束,确保T只能是可实例化的具体类构造函数:
abstract class Base extends HTMLElement { abstract doSomething(): void; // 泛型约束改为可实例化的构造函数类型 static register<T extends new (...args: any[]) => Base>(type: T) { // Other code customElements.define("custom", type); } } class Impl extends Base { doSomething(): void { // 实现抽象方法逻辑 } static register() { Base.register(this); } }
原理说明
new (...args: any[]) => Base是构造函数类型签名,代表可以通过new关键字创建Base实例的构造函数,抽象类的构造函数不符合这个签名(因为抽象类无法被实例化),因此自动排除了抽象类型。- 这个约束既保留了
T必须继承Base的要求,又满足了CustomElementConstructor对具体构造函数的要求,彻底解决类型错误。
内容的提问来源于stack exchange,提问作者Luke Vo
相关产品推荐
相关产品推荐

