question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Exported TypeScript namespaces don’t compile properly with new SWC compiler

See original GitHub issue

What version of Next.js are you using?

12.0.0

What version of Node.js are you using?

16.6.2

What browser are you using?

N/A

What operating system are you using?

macOS

How are you deploying your application?

N/A

Describe the Bug

In our Next.js 11 sites we use exported TypeScript namespaces for some shared package and style modules. It’s maybe ill-advised to use namespaces like this but it lets us write code like this:

namespace appValues {
  const firstName = "Foo";
  const lastName = "Bar";

  export const fullName = `${firstName} ${lastName}`
}

export default appValues;

Which is roughly equivalent to this:

const firstName = "Foo";
const lastName = "Bar";

const appValues = {
  fullName: `${firstName} ${lastName}`
}

export default appValues;

Unfortunately this isn’t working in Next.js 12 when SWC is used, presumably because SWC compiles this namespace code (AFAIK) incorrectly.

Expected Behavior

If appValues is imported in another file this code should log “Foo Bar”:

import appValues from 'appValues'

console.log(appValues.fullName)

This would work in Next.js 11, but fails in Next.js 12 with Cannot read property 'fullName' of undefined.

To Reproduce

Here’s a reproduction based on the latest create-next-app (with the typescript preset):

https://github.com/GrantASL19/nextjs-12-typescript-namespace-default-export-error

Note that VS Code doesn’t flag any type errors, but the build fails.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:1
  • Comments:5

github_iconTop GitHub Comments

1reaction
hockduducommented, Nov 3, 2021

I have the same problem on my project after updating to Next.js 12.

namespace DateFormatter {
    export function getFormattedDate(date: Date): string {
        // ...
    }
}

export default DateFormatter;

If I try to use it somewhere else:

const formattedDate = DateFormatter.getFormattedDate(new Date());

TypeError: Cannot read properties of undefined (reading 'getFormattedDate')


I noticed, if I save the namespace to a variable first, then it works:

namespace DateFormatter {
    // ...
}

const dateFormatter = DateFormatter;

export default dateFormatter;

Nonetheless, I should be able to export the namespace without saving it to a variable first.

0reactions
GrantASL19commented, Apr 19, 2022

I updated my reproduction again.

In case anyone else is blocked by this, I also found a simpler fix, which I’ve included in a comment in my repo. I hope this also helps debug the issue in SWC/Next.js.

If this module is exported from another module it will be undefined:

namespace appValues {
  const firstName = "Foo";
  const lastName = "Bar";
  export const fullName = `${firstName} ${lastName}`
}

export default appValues;

Whereas this will work as expected (replaced export default appValues; with export default (appValues);:

namespace appValues {
  const firstName = "Foo";
  const lastName = "Bar";
  export const fullName = `${firstName} ${lastName}`
}

export default (appValues);
Read more comments on GitHub >

github_iconTop Results From Across the Web

Namespaces are not exported properly #4393 - GitHub
I am trying to replace babel with swc in a webpack project but I have stumbled upon an issue regarding namespaces: ...
Read more >
isolatedModules - TSConfig Option - TypeScript
'index.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export ......
Read more >
PR that converts the TypeScript repo from namespaces to ...
After this change, the TypeScript compiler will now be compiled with esbuild. I feel like thats probably the best endorsement esbuild could ...
Read more >
How To Use Namespaces in TypeScript | DigitalOcean
This code will now compile correctly and have correct types for the Vector3 class. Using namespaces, you can isolate what is exported by...
Read more >
Using eslint with typescript - Unable to resolve path to module
The module.exports = { resolve: { extensions: ['.js', '.ts'] } }; bit should be in your webpack config!
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found