未捕获的TypeError:Typescript扩展方法不是函数
我正在尝试为数组编写一个扩展方法。每当程序运行代码时,我都会得到未捕获的TypeError:Typescript扩展方法不是函数,typescript,Typescript,我正在尝试为数组编写一个扩展方法。每当程序运行代码时,我都会得到uncaughttypeerror:pairs.map(…).flatte不是一个函数。下面是代码的样子: 扩展名 declare interface Array<T> { flatten<T>(): T; } Array.prototype.flatten = function<T> () : T { return this.reduce(function (flat: Array&l
uncaughttypeerror:pairs.map(…).flatte不是一个函数。下面是代码的样子:
扩展名
declare interface Array<T> {
flatten<T>(): T;
}
Array.prototype.flatten = function<T> () : T {
return this.reduce(function (flat: Array<T>, toFlatten: Array<T>) {
return flat.concat(Array.isArray(toFlatten) ? toFlatten.flatten() : toFlatten )
}, []);
}
我已尝试将Array.prototype.flatte=function():T{…
更改为Array.prototype.flatte=():T=>{…
和pairs.map(pair=>pair.start.concat(pair.end)).flatte()
更改为pairs.map(pair=>pair.start.concat(pair.end)).flatte()
,但它没有做任何事情
我在这里的某个地方也读到过,这可能是一个传输问题,因此我将--target
编译器更改为ESNext
,但错误仍然不断出现。欢迎这样做,b12629不幸的是,TypeScript在编译时加载模块的方式与Javascript加载模块的方式明显不同在运行时编译模块(特别是在使用React或Jest等具有自己的Javascript模块加载系统的框架时)。模块加载系统中的这种差异意味着,即使您的代码已编译,也可能在运行时失败(它是否失败在很大程度上取决于您正在使用的特定框架和模块导入/导出,从而导致非常脆弱的代码)。因此,很难在TypeScript中可靠地使用扩展方法,因此建议使用替代方法(例如帮助器方法、自定义类等)
但是,如果您真的想让扩展方法发挥作用,请继续阅读
基本上,此错误意味着TypeScript在编译时已正确定位接口扩展:
declare interface Array<T> {
flatten<T>(): T;
}
声明接口数组{
展平():T;
}
但是Javascript没有在运行时执行扩展原型的调用:
Array.prototype.flatten = function<T> () : T {
return this.reduce(function (flat: Array<T>, toFlatten: Array<T>) {
return flat.concat(Array.isArray(toFlatten) ? toFlatten.flatten() : toFlatten )
}, []);
}
Array.prototype.flant=function():T{
返回此.reduce(函数(flat:Array,toFlatten:Array){
返回flat.concat(Array.isArray(toFlatten)?toFlatten.flatten():toFlatten)
}, []);
}
不幸的是,目前接受的答案和StackOverflow上的其他相关答案只提到将定义放在“顶级文件”中,而“顶级文件”并没有给出足够清晰的说明来处理所有场景(请参阅,
及)
若要调试不一致的行为,可以在原型扩展调用上放置断点,以查看何时/是否调用它。还可以检查扩展类的proto
字段,以检查扩展方法是否已在运行时创建。请记住,由于使用JavaScript来计算这一行
要确保原型扩展调用发生,请找到所有应用程序入口点(例如Jest测试、web framework global等),并确保从每个入口点调用原型扩展调用(粗略的解决方案是在每个入口点的开头调用“setup”方法)。注意:请记住Jest和其他测试库可以模拟模块,因此您希望确保从不模拟调用原型扩展名的模块。实际上,这意味着您应该为扩展名使用单独的文件,并禁用Jest自动模拟(或等效文件).谢谢!我通过将展平
定义放在value.ts
文件的顶部来实现它。我可以将展平
定义和接口数组
声明放在1extensions.ts
文件中吗?如果可以,我应该将extensions.ts
放在哪里?我已经尝试过将它放在src
文件夹、app
文件夹和我创建的models
文件夹,但我仍然收到运行时错误。我建议保留您的声明(declare…
)在一个单独的文件中,例如,它可以是extensions.d.ts
。那么剩下的部分放在哪里完全取决于您自己,只要您在使用原型之前扩展它。它可以在同一个文件中,或者在您调用新定义的函数之前需要的另一个模块中。
Array.prototype.flatten = function<T> () : T {
return this.reduce(function (flat: Array<T>, toFlatten: Array<T>) {
return flat.concat(Array.isArray(toFlatten) ? toFlatten.flatten() : toFlatten )
}, []);
}