You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:36:04