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
相关产品推荐
相关产品推荐

