TypeScript如何限制函数仅接受抽象类的非抽象子类作为参数
解决思路
核心是将createPerson的入参类型从抽象类类型typeof Person替换为可实例化、实例类型继承自Person的构造函数类型,天然就排除了抽象的Person本身(抽象类不存在可调用的构造签名,无法匹配该类型约束),同时兼容子类构造函数的参数校验。
修改后完整代码
abstract class Person { protected abstract type?: string constructor(private name: string) {} protected greet() { console.log(`Hello ${this.name}`) } } class Student extends Person { type = "Student" constructor(type: string) { super(type) } } class Teacher extends Person { type = "teacher" constructor(type: string) { super(type) } } // 核心类型修改 function createPerson<T extends Person>( ClassThatInheritsPerson: new (...args: ConstructorParameters<typeof T>) => T, ...args: ConstructorParameters<typeof T> ): T { return new ClassThatInheritsPerson(...args) } const teacher1 = createPerson(Teacher, "张老师") // 正常允许 const student1 = createPerson(Student, "李同学") // 正常允许 const person = createPerson(Person, "测试") // 抛出类型错误:无法将抽象类型 Person 分配给类型 "new (...args: any[]) => Person"
生效说明
- 入参类型
new (...args: ConstructorParameters<typeof T>) => T显式要求传入的是可被new调用的构造函数,抽象类Person的构造为抽象类型,不满足约束,传入时直接触发类型报错 - 泛型自动匹配传入子类的实例类型,返回值精度高于固定返回
Person ConstructorParameters自动匹配对应子类的构造参数类型,调用时会自动给出参数类型提示,避免参数传错
内容的提问来源于stack exchange,提问作者somerandomdrunkcoder
相关产品推荐
相关产品推荐

