-
Notifications
You must be signed in to change notification settings - Fork 28.9k
Verify canary release
- I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: linux
Arch: x64
Version: #22 SMP Tue Jan 10 18:39:00 UTC 2023
Binaries:
Node: 16.17.0
npm: 8.15.0
Yarn: 1.22.19
pnpm: 7.1.0
Relevant packages:
next: 13.2.4-canary.0
eslint-config-next: N/A
react: 18.2.0
react-dom: 18.2.0
Which area(s) of Next.js are affected? (leave empty if unsure)
TypeScript support
Link to the code that reproduces this issue
https://codesandbox.io/p/sandbox/floral-thunder-44jpww?file=%2Fpages%2Findex.tsx
To Reproduce
- Open reproduction above
- Observe TypeScript error on
dynamic()
functionThis expression is not callable. Type 'typeof import("/project/sandbox/node_modules/next/dynamic")' has no call signatures.
- Observe TypeScript error on
Image
componentJSX element type 'Image' does not have any construct or call signatures.typescript(2604)
This occurs with all import paths with slashes into next
eg:
next/dynamic
next/image
next/link
next/navigation
next/script
Describe the Bug
The TypeScript types for the imports at the paths mentioned above fail when using:
- ESM (
"type": "module"
inpackage.json
) - TSConfig
"module": "node16"
, which was seemingly implemented by @loettz in Add support for tsconfig 'nodenext' | 'node16' #44177
The code however still runs, so it seems to be a problem with the Next.js types and ESM <> CommonJS interop.
I'm guessing that since Next.js is CommonJS, the types of these exports on all *.d.ts
files are actually wrong:
next.js/packages/next/link.d.ts
Lines 1 to 3 in ed51bd8
import Link from './dist/client/link' | |
export * from './dist/client/link' | |
export default Link |
I guess the correct type would actually use the unusual TypeScript syntax export =
, like my PR over here:
https://github.com/DefinitelyTyped/DefinitelyTyped/pull/64137/files
cc @andrewbranch @fluggo @cseas @lfades
Workaround
A workaround is to type the import as the .default
property, as @kachkaev shows in this discussion comment:
-import x from "x";
+import _x from "x";
+const x = _x as unknown as typeof _x.default;
Expected Behavior
The import should work out of the box and no TypeScript errors should appear.
See also
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response