TypeScript工厂模式中带never的返回类型与直接用Interface的区别
问题1:为什么使用ExtractInstanceType而非直接返回IStaff接口
如果你的所有用户类(Manager、Engineer等)都实现了IStaff接口,直接返回IStaff确实可以正常运行,但存在两个明显缺陷:
- 丢失了子类的特有类型信息:比如Manager类有独有的
approveBudget()方法,如果你把返回值限定为IStaff,调用这个方法时TS会提示属性不存在,必须手动做类型断言才能使用 - 无法配合参数做自动类型推导:如果工厂方法的入参和返回值做了泛型绑定,传特定key时TS可以自动推导出对应的子类实例类型,返回
IStaff会完全丢失这个能力
你看到的ExtractInstanceType本质就是TS内置工具类型InstanceType<T>的手动实现,作用是从构造函数类型中提取对应的实例类型,返回的是所有子类实例的联合类型(比如Manager | Engineer),既兼容IStaff的公共属性方法,也保留了子类的特有类型信息,后续做类型收窄也更方便。
问题2:Keys类型的含义
你的理解基本正确,它确实是userMap字典允许的键的集合,但不是普通的字符串类型,一般是字面量联合类型。比如userMap定义为:
const userMap = { manager: Manager, engineer: Engineer }
那么Keys通常是keyof typeof userMap,也就是'manager' | 'engineer'的字面量联合类型。和用string做参数类型相比,它可以在编译阶段就拦截非法的键值输入,类型安全性更高。
问题3:能否传入对象实例作为getUser的参数
完全不可行。
首先参数类型不匹配:getUser要求入参是Keys类型的字面量,你传入的manager是Manager类的实例,类型完全对不上,TS在编译阶段就会直接报错。
其次逻辑也不通:工厂方法的作用就是根据标识生成新的实例,你已经有实例的情况下完全不需要调用工厂方法,要生成新的Manager实例直接传入对应键即可:const anotherManager = UserFactory.getUser('manager')
内容的提问来源于stack exchange,提问作者JC1700
相关产品推荐
相关产品推荐

