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

JavaScript代码转TypeScript最优方案咨询:多类共用函数及接口使用

TypeScript 重写最佳实现方案

先纠正原有代码的逻辑问题

你原有的JavaScript代码中把sayHello定义为静态方法是错误的:静态方法内部的this指向类构造函数本身,而非实例对象,你调用Director.sayHello()时根本无法获取到实例的firstName、lastName属性,输出结果不符合预期。

关于Person接口的必要性

非常建议定义Person接口/抽象基类来统一约束firstName、lastName属性,既可以避免三个类中重复写属性类型声明,也能提升代码可读性、可维护性,后续要新增公共属性只需要修改一处即可。

推荐实现方案

方案1:抽象基类继承(最适配当前场景,代码复用率最高)

如果你的三个类没有其他父类,优先用抽象基类实现,公共属性、公共方法都封装在基类中,不需要重复写逻辑:

// 抽象基类,封装公共属性和方法
abstract class Person {
  firstName: string;
  lastName: string;

  constructor(firstName: string, lastName: string) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  // 公共实例方法,所有子类继承后可直接调用
  sayHello(): void {
    console.log(`Hi, my name is ${this.firstName} ${this.lastName}`);
  }

  // 如果确实需要静态调用,传入Person类型的实例即可
  static sayHello(person: Person): void {
    console.log(`Hi, my name is ${person.firstName} ${person.lastName}`);
  }
}

class Guest extends Person {
  constructor(firstName: string, lastName: string) {
    super(firstName, lastName);
  }
}

class Employee extends Person {
  permissionLevel: string;

  constructor(firstName: string, lastName: string, permissionLevel: string) {
    super(firstName, lastName);
    this.permissionLevel = permissionLevel;
  }
}

class Director extends Person {
  constructor(firstName: string, lastName: string) {
    super(firstName, lastName);
  }
}

// 调用示例
const clerk = new Employee('张三', '李', 'level2');
clerk.sayHello(); // 输出:Hi, my name is 张三 李

const director = new Director('John', 'Smith');
director.sayHello(); // 输出:Hi, my name is John Smith

// 静态方法调用
Person.sayHello(director);
Director.sayHello(director);

方案2:接口+组合(适合类已经有其他父类的场景)

如果你的三个类已经继承了其他父类无法再继承Person基类,可以用接口约束+公共工具函数的方式实现:

// 统一约束公共属性
interface Person {
  firstName: string;
  lastName: string;
}

// 抽离公共方法,参数限定为Person类型保证类型安全
function sayHello(person: Person): void {
  console.log(`Hi, my name is ${person.firstName} ${person.lastName}`);
}

class Guest implements Person {
  firstName: string;
  lastName: string;

  constructor(firstName: string, lastName: string) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  // 也可以在类内部封装一层方法,直接调用公共逻辑
  sayHello() {
    sayHello(this);
  }
}

class Employee implements Person {
  firstName: string;
  lastName: string;
  permissionLevel: string;

  constructor(firstName: string, lastName: string, permissionLevel: string) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.permissionLevel = permissionLevel;
  }

  sayHello() {
    sayHello(this);
  }
}

class Director implements Person {
  firstName: string;
  lastName: string;

  constructor(firstName: string, lastName: string) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  sayHello() {
    sayHello(this);
  }
}

// 调用示例
const clerk = new Employee('张三', '李', 'level2');
clerk.sayHello();

const director = new Director('John', 'Smith');
sayHello(director); // 也可以直接调用公共方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:06:03