【问题标题】:Why does typescript infer a default prop when we dynamically import a javascript file which does not have a default export当我们动态导入没有默认导出的javascript文件时,为什么打字稿会推断出默认道具
【发布时间】:2021-02-28 10:06:06
【问题描述】:

我正在动态导入导出多个函数的 javascript 文件(并且没有默认导出) const sayHi = import('./sayHi.js')

我希望 sayHi 的类型是 Promise<{name1: function, name2: function}> 但它是 Promise<{default: typeof import('./sayHi.js'), name1: function, name2: function}>

为什么要添加默认道具

这是一个代码框 https://codesandbox.io/s/typescript-dynamic-import-w4nb1?file=/src/index.tsx

为什么__promise__ 会自动添加默认道具?

【问题讨论】:

  • @NicholasTower 对不起我的错误。我已经更正了链接以显示类型错误。您可以将鼠标悬停在第 6 行的红色波浪线上
  • 你能记录下 promise 结果,看看它在运行时的实际样子吗?我猜“默认”属性的存在是为了确保在 module.exports 被覆盖时的互操作性,而不是在其上设置属性。
  • @JonasWilms 谢谢。我确实记录了它,但没有默认道具。随意看看这个叉子,我在哪里做过。 codesandbox.io/s/typescript-dynamic-import-forked-oxjqo?file=/…
  • 这怎么是一个javascript问题
  • 可能与tsconfig中的allowSyntheticDefaultImports有关:typescriptlang.org/tsconfig#allowSyntheticDefaultImports

标签: javascript reactjs typescript es6-promise es6-modules


【解决方案1】:

合成默认导出

tsconfig 文件中有一个名为 allowSyntheticDefaults 的选项,它允许 typescript 支持 Babel 为没有显式默认值的文件创建默认导出。默认对象是包含该文件中所有命名导出的键控对象。如果此设置为 true,则所有文件都将在其命名导出旁边包含一个名为 default 的导出。

输入makeDefaultExport

您的函数 makeDefaultExport 仅使用文件中的一个特定命名导出,因此我们可以对该函数应用更严格的 typecipt 类型并获得更具体的返回。我们使用第二个通用K 来代替keyof T 作为密钥。

export const makeDefaultExport = <T, K extends keyof T>(
  promise: Promise<T>, key: K
) => {

现在此函数将仅返回特定命名导出的类型,而不是所有导出的并集(包括默认值)。返回类型为:

Promise<{ default: T[K]; }>

编辑:我推荐上述方法,因为它可以正确处理并非所有命名导出都具有相同类型的文件。在您的特定情况下,所有导出都是相同的类型,因此我们不会通过返回除default 之外的所有导出类型的联合来扩大任何类型。

export const makeDefaultExport = <T>(
  promise: Promise<T>, key: Exclude<keyof T, "default">
) => {

【讨论】:

猜你喜欢
  • 2019-12-11
  • 2017-02-06
  • 2016-01-23
  • 2019-11-23
  • 2021-11-24
  • 2017-09-23
  • 2016-02-10
  • 2020-07-08
  • 2021-02-07
相关资源
最近更新 更多