TypeScript如何让类自动继承接口属性以避免重复定义?
TypeScript 接口与类的无冗余实现方案
需求概述
我需要定义如下TypeScript接口:
interface SquareConfig { color: string; width: number; }
希望创建一个实现该接口的类,但无需手动重复定义接口中的属性,期望的写法如下:
class MyClass implements SquareConfig { // 无需重复写color、width属性定义 } let mc = new MyClass() mc.color = 'blue' // 可正常运行 mc.width = 12 // 可正常运行
要避免的冗余写法:
class MyClass implements SquareConfig { color: string; width: number; }
核心原因
- 处理大量属性时,重复定义违反DRY原则
- 必须手动保持类属性与接口的同步,维护成本高
- 场景背景:用typia对JSON做运行时类型检查后,需要将校验后的JSON初始化实现同一接口的类实例
可行解决方案
方案1:构造函数结合Object.assign自动赋值
通过构造函数接收符合接口的配置对象,利用Object.assign将属性批量挂载到类实例上,同时借助TypeScript的类型检查确保合规:
interface SquareConfig { color: string; width: number; } class MyClass implements SquareConfig { constructor(config: SquareConfig) { Object.assign(this, config); } } // 使用示例:基于typia校验后的JSON初始化实例 const validatedJson = typia.assert<SquareConfig>(rawJson); const mc = new MyClass(validatedJson); mc.color = 'red'; // 类型检查通过 mc.width = 20; // 类型检查通过
这种方式既避免了属性重复定义,又保证了类实例与接口的类型一致性,同时支持后续修改属性。
方案2:工厂函数包装类实例
如果不需要在类中定义构造函数,可以用工厂函数将校验后的配置对象合并到空类实例上:
interface SquareConfig { color: string; width: number; } class MyClass implements SquareConfig {} function createMyClass(config: SquareConfig): MyClass { return Object.assign(new MyClass(), config); } // 使用示例 const validatedJson = typia.assert<SquareConfig>(rawJson); const mc = createMyClass(validatedJson);
类本身仅作为接口的实现标记,工厂函数负责完成属性的挂载,同样满足类型安全要求。
补充说明
TypeScript本身不支持让类自动“继承”接口的属性定义——因为接口是编译时的类型约束,而类是运行时的实体。上述方案通过运行时属性赋值 + 编译时类型校验的组合,既满足了无冗余的需求,又保证了类型一致性,完美适配结合typia做运行时校验的场景。
内容的提问来源于stack exchange,提问作者Josh Diehl
相关产品推荐
相关产品推荐

