I am dynamically importing a javascript file that exports multiple functions (and does not have a default export)
const sayHi = import('./sayHi.js')
I am expecting sayHi's type to be Promise<{name1: function, name2: function}>
but it is
Promise<{default: typeof import('./sayHi.js'), name1: function, name2: function}>
why does the default prop get added
Here is a codesandbox https://codesandbox.io/s/typescript-dynamic-import-w4nb1?file=/src/index.tsx
why does __promise__
have a default prop automatically added?
There is an option in your tsconfig
file called allowSyntheticDefaults
which allows typescript to support Babel's creation of default exports for files which do not have an explicit default. The default object is a keyed object containing all of the named exports from that file. If this setting is true
then all files will have an export called default
included alongside their named exports.
makeDefaultExport
Your function makeDefaultExport
only uses one specific named export from the file, so we can apply stricter typescipt typings to this function and get a more specific return. Instead of just keyof T
, we use a second generic K
for the key.
export const makeDefaultExport = <T, K extends keyof T>(
promise: Promise<T>, key: K
) => {
Now this function will return only the type for the specific named export instead of the union of all exports (which was including the default). The return type is:
Promise<{ default: T[K]; }>
Edit: I recommend the above approach as it properly handles files where not all named exports have the same type. In your particular case all of the exports are the same type, so we won't get any type widening by returning a union of all export types except the default
.
export const makeDefaultExport = <T>(
promise: Promise<T>, key: Exclude<keyof T, "default">
) => {