当我们动态导入没有默认导出的 javascript 文件时,为什么打字稿会推断出默认道具

Why does typescript infer a default prop when we dynamically import a javascript file which does not have a default export

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

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

为什么要添加默认道具

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

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

合成默认导出

您的 tsconfig 文件中有一个名为 allowSyntheticDefaults 的选项,它允许打字稿支持 Babel 为没有明确默认值的文件创建默认导出。默认对象是一个键控对象,其中包含该文件中的所有命名导出。如果此设置为 true,则所有文件都将包含一个名为 default 的导出及其命名导出。

正在键入 makeDefaultExport

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

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

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

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

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

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