TypeScript编写functional mixins无法识别新增方法如何解决
问题原因
你对mixin入参的o: object类型标注导致TypeScript丢失了入参的具体结构信息,后续叠加的mixin新增属性无法被递归保留到最终返回的实例类型中。
解决方案
使用泛型约束入参为对象类型,同时保留入参的具体类型结构,TypeScript会自动推导mixin叠加后的交叉类型,完整识别所有属性方法。
修复后的完整代码
// 泛型T约束入参为对象,同时保留入参的具体类型 const flying = <T extends object>(o: T) => { let isFlying = false; return Object.assign({}, o, { fly() { isFlying = true; return this; }, isFlying: () => isFlying, land() { isFlying = false; return this; } }); }; const quacking = (quack: string) => <T extends object>(o: T) => Object.assign({}, o, { quack: () => quack }); const createDuck = (quack: string) => flying(quacking(quack)({})); const duck = createDuck('Quack!'); duck.isFlying(); // 正常识别 ✅ duck.quack(); // 正常识别 ✅
如果你偏好使用对象展开运算符替代Object.assign,写法如下,类型推导效果完全一致:
const flying = <T extends object>(o: T) => { let isFlying = false; return { ...o, fly() { isFlying = true; return this; }, isFlying: () => isFlying, land() { isFlying = false; return this; } } };
原理解释
泛型<T extends object>实现了两个核心能力:
- 约束入参必须为对象类型,符合对象合并操作的类型要求
- 完整保留入参的类型结构,TypeScript会自动将入参类型和mixin新增的方法类型做交叉合并,多层mixin叠加的所有属性方法都会被正确识别。
内容的提问来源于stack exchange,提问作者J. Hesters
相关产品推荐
相关产品推荐

