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

如何为基类exec方法添加强类型,使其仅接受派生类实例方法名?

限制基类方法仅接受派生类的实例方法名称

我们可以通过自定义类型工具结合this类型,实现基类方法仅接受派生类实例方法名称的强类型约束,以下是完整解决方案:

// 自定义类型工具:提取对象类型中所有值为函数的键
type MethodKeys<T> = { 
  [K in keyof T]: T[K] extends Function ? K : never 
}[keyof T];

abstract class Animal {
    abstract species: string;

    breathe() {
        console.log(`Ahh`);
    }

    // 使用MethodKeys<this>限定参数仅为当前实例的方法名称
    exec(methodName: MethodKeys<this>) {
        (this[methodName] as () => void)();
    }
}

class Cat extends Animal {
    lovesCatnip = true;
    species = `felis catus`;

    meow() {
        console.log(`Meow`);
    }
}

class Dog extends Animal {
    chasesCars = true;
    species = `canis familiaris`;

    bark() {
        console.log(`Woof`);
    }
}

const fido = new Dog();
fido.exec(`breathe`); // ✅ 正常通过类型检查
fido.exec(`bark`); // ✅ 正常通过类型检查
fido.exec(`species`); // ❌ 类型报错:"species"不属于方法名称类型
fido.exec(`chasesCars`); // ❌ 类型报错:"chasesCars"不属于方法名称类型

const snowball = new Cat();
snowball.exec(`breathe`); // ✅ 正常通过类型检查
snowball.exec(`meow`); // ✅ 正常通过类型检查
snowball.exec(`species`); // ❌ 类型报错
snowball.exec(`lovesCatnip`); // ❌ 类型报错

核心逻辑说明

  1. MethodKeys<T>类型工具:通过映射类型遍历T的所有键,仅保留值为函数类型的键,最终生成该类型下所有方法名称的联合类型。
  2. this类型的动态推导:当派生类实例调用基类的exec方法时,TypeScript会自动将this推导为派生类的实例类型(如Dog或Cat),因此MethodKeys<this>会精准提取当前派生类的所有方法名称,自动排除普通属性。
  3. 严格类型约束:相比直接使用keyof this,这种方式从类型层面就限制了参数只能是方法名称,彻底避免传入属性名导致的运行时风险。

内容的提问来源于stack exchange,提问作者RobertAKARobin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:49:52