TypeScript如何合并类型与类实现,仅导出单个实体同时支持实例化与类型标注
解决方案
利用TypeScript的同名声明合并特性,导出同名的接口和构造函数即可,对外仅暴露单个MyClass实体,同时满足实例创建和类型标注的需求。
完整实现代码
// 内部类型与实现,不对外导出 type MyClassType = { state: 0; data: { p1: boolean; }; } | { state: 1; data: { p2: boolean; }; } | { state: 2; data: { p3: boolean; }; } class MyClassImplementation { state = 0; data = { p1: true }; // 后续新增实例方法直接在这里定义即可 } // 同名接口:类型标注时的MyClass会指向该接口 export interface MyClass extends MyClassType {} // 同名构造函数:new MyClass()时会走该值的定义 export const MyClass = MyClassImplementation as { new (): MyClassType; }
使用示例
// 1. 作为构造函数创建实例 const ins = new MyClass() // 2. 作为类型标注使用,自动支持联合类型缩小推导 function handleMyClass(c: MyClass) { if (c.state === 1) { c.data.p2 // 类型正常推导,无报错 } if (c.state === 2) { c.data.p3 // 类型正常推导,无报错 } }
原理说明
TypeScript支持同名的接口和值声明进行合并,导出后:
- 值层面的
MyClass是定义的构造函数,可以直接new创建实例 - 类型层面的
MyClass是定义的接口,直接匹配联合类型MyClassType的结构
不需要对外暴露内部的MyClassType和MyClassImplementation,完全符合需求。
优化建议
如果需要避免后续新增实例属性/方法时重复定义类型,可以调整MyClassType的定义,自动继承实现类的类型:
type MyClassType = MyClassImplementation & ( { state: 0; data: { p1: boolean }; } | { state: 1; data: { p2: boolean }; } | { state: 2; data: { p3: boolean }; } )
内容的提问来源于stack exchange,提问作者Just Alex
相关产品推荐
相关产品推荐

