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

问题描述

我正在动态导入一个导出多个函数的 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__自动添加默认道具? 在此处输入图像描述

标签: javascriptreactjstypescriptes6-promisees6-modules

解决方案


合成默认导出

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

打字makeDefaultExport

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

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">
) => {

推荐阅读