如何在TypeScript泛型中排除Function类型实现非函数克隆?
解决TypeScript泛型中排除Function类型的问题
structuredClone 或 lodash.cloneDeep 无法克隆函数,想要在泛型函数中排除Function类型,但直接使用Exclude<T, Function>或类似写法时,传入类的this会触发类型错误。
问题原因
直接使用Exclude<T, Function>会误将类实例判定为Function的子类型——因为类实例的原型上包含call/apply等方法签名,导致TypeScript错误地认为类实例属于Function类型范畴。
解决方案
使用条件类型精确排除“本身就是函数”的类型,而非包含函数属性的对象:
type NonFunction<T> = T extends Function ? never : T; function cloneAnythingButFunction<T>(object: NonFunction<T>): T { return structuredClone(object); } // 预期报错:传入函数本身会被拦截 cloneAnythingButFunction(cloneAnythingButFunction); // 预期无报错:类实例和类方法中的this都能正常传入 class Test{ clone(){ return cloneAnythingButFunction(this); } } const test = new Test(); cloneAnythingButFunction(test);
原理说明
NonFunction<T>条件类型会严格检查T是否直接是Function类型:如果是则返回never(禁止传入),否则保留原类型。- 类实例本身不属于
Function类型,只是其原型上挂载了方法,因此不会被条件类型误判,能正常通过类型检查。
内容的提问来源于stack exchange,提问作者Clifford B. Wolfe
相关产品推荐
相关产品推荐

