当我们动态导入没有默认导出的 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">
) => {
我正在动态导入导出多个函数的 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">
) => {