程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了从 pg-promise 示例中的“pg-promise”导入 * 作为 pgPromise 导致打字稿错误 TS2349:此表达式不可调用大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决从 pg-promise 示例中的“pg-promise”导入 * 作为 pgPromise 导致打字稿错误 TS2349:此表达式不可调用?

开发过程中遇到从 pg-promise 示例中的“pg-promise”导入 * 作为 pgPromise 导致打字稿错误 TS2349:此表达式不可调用的问题如何解决?下面主要结合日常开发的经验,给出你关于从 pg-promise 示例中的“pg-promise”导入 * 作为 pgPromise 导致打字稿错误 TS2349:此表达式不可调用的解决方法建议,希望对你解决从 pg-promise 示例中的“pg-promise”导入 * 作为 pgPromise 导致打字稿错误 TS2349:此表达式不可调用有所启发或帮助;

在我的程序中调整推荐的打字稿示例

import * as pgPromise from 'pg-promise' ;
const pg = pgPromise() ;

没有用。第二行导致错误:

This Expression is not callable. Type 'typeof pgPromise' has no call signatures.ts(2349)

谷歌搜索错误消息没有返回似乎与模块导入相关的答案,因为它们都处理调用不可调用的对象。但是,我需要一种不同的解释:我不知道为什么 import 语句会产生一个非函数对象,尽管明显作者的意图是返回一个函数,该函数可以使用许多参数初始化底层模块。

分析模块源代码没有太大帮助,它是用JavaScript编写的,看起来不太透明。

解决方法

最后我自己找到了答案。

示例中存在错误。原进口申报:

import * as pgPromise from 'pg-promise' ;

导致错误,如问题中所述。正确的语法是:

import pgPromise from 'pg-promise' ;

然后它按预期工作。

,

这是一个与转译为 javascript 和 ES6 规范相关的问题,而不是特定于 pg-promise

解决这个问题至少有两种可能的方法:

  1. 使用不同的语法:
import pgPromise from 'pg-promise' ;

这一行按原样导入默认导出对象(在本例中为函数)。它更短,在我看来比以下行更直观,在示例中使用并由模块作者推荐:

import * as pgPromise from 'pg-promise' ;

要求,导入的对象是一个对象(因为 * 表示将其所有属性导入主命名空间),因此它确实导入了所有导出的属性,但不是函数,因为函数未分配给属性,它是对象本身。

为了更详细地解释差异,

这是一个“普通”对象:

// module "module-p.js"
let p = { name: 'John',colour: 'blue',age: 1263 }
export default p ;

这是一个带有属性的函数对象:

let p = (X) => { console.log(X); } ;
p.name = 'John';
p.colour = 'blue';
p.age = 1263;
export default p ;

后者,当被导入时

import * as P from 'module-p';

将导入对象属性 namecolourage,并将它们分配给当前命名空间中的对象 P。但是,它不会从上面的例子中导入函数 p(),因为它在 p;

中没有命名属性
  1. 快速而肮脏的解决方案是修复 esModuleInterop 中的选项 tsconfig.json
"esModuleInterop": true

"esModuleInterop": false

更改该选项将启用 javascript 模块 pg-promise 和其他以类似 javascript 风格编写的模块所需的轻松模块导入处理。

https://www.typescriptlang.org/tsconfig#esModuleInterop 说:

默认情况下(使用 esModuleInterop false 或未设置)TypeScript 将 CommonJS/AMD/UMD 模块视为类似于 ES6 模块。在这样做时,特别是有两个部分被证明是有缺陷的假设:

@H_801_123@
  • 像 import * as moment from "moment" 这样的命名空间导入与 const moment = require("moment") 的作用相同

  • 像 import moment from "moment" 这样的默认导入与 const moment = require("moment").default

  • 这种不匹配导致了这两个问题:

    @H_801_123@
  • ES6 模块规范声明命名空间导入(import * as x)只能是一个对象,通过让 TypeScript 将其视为 = require("x") 然后 TypeScript 允许import 被视为一个函数并且是可调用的。这违反了规范的建议。

  • 然符合 ES6 模块规范,但大多数带有 CommonJS/AMD/UMD 模块的库并不像 TypeScript 的实现那样严格。

  • pg-promise 导入依赖于特定的 Typescript 转译器配置的原因似乎是导出的命名空间是一个函数,而不是一个对象,这在 esModuleInterop = true 时是不允许的。 pg-promise 文档没有提到任何特定的 typescript 配置依赖项或要求。

    遗憾的是,pg-promise 的作者决定在这里留下傲慢的评论,而不是在答案中指出打字稿问题。

    大佬总结

    以上是大佬教程为你收集整理的从 pg-promise 示例中的“pg-promise”导入 * 作为 pgPromise 导致打字稿错误 TS2349:此表达式不可调用全部内容,希望文章能够帮你解决从 pg-promise 示例中的“pg-promise”导入 * 作为 pgPromise 导致打字稿错误 TS2349:此表达式不可调用所遇到的程序开发问题。

    如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
    标签:*作为