Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UnsupportedSyntaxError: namespace child (hoisting) not supported #162

Closed
3 tasks done
skaneprime opened this issue Aug 1, 2021 · 12 comments
Closed
3 tasks done

UnsupportedSyntaxError: namespace child (hoisting) not supported #162

skaneprime opened this issue Aug 1, 2021 · 12 comments
Labels
wontfix This will not be worked on

Comments

@skaneprime
Copy link

skaneprime commented Aug 1, 2021

Checklist

  • I can reproduce this issue when running this plugin on its own.
    Other plugins, such as node-resolve are known to cause issues.
  • I am running this plugin on .d.ts files generated by TypeScript.
    The plugin can consume .ts and even .js files (with allowJs: true), but this is known to cause issues.
  • This issue is not related to rolling up @types.
    The plugin ignores these by default, unless respectExternal is set. @types can contain hand-crafted code which is known to cause issues.

Code Snipped

// Client.ts
import * as Mods from './modules'

export class Client {
    Services = new Mods.Services()
}
export namespace Client {
    export import Services = Mods.Services
}
// ./modules/index.ts
export * from './Services'
// ./modules/Services.ts
export namespace Services {
    export type Type = "ServiceType"
}
export class Services {}

Error Message

// The Error Message thrown by rollup / the plugin.
Failed to build: UnsupportedSyntaxError: namespace child (hoisting) not supported yet
   6 | declare namespace Client {
>  7 |     export import Services = Mods.Services;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   8 | }
   9 |
  10 | export { Client };
Swatinem added a commit that referenced this issue Aug 2, 2021
@Swatinem
Copy link
Owner

Swatinem commented Aug 2, 2021

I experimented with fixing this, but rollup flattens all the imports into the global namespace, and typescript does not allow re-declarations, which is super annoying, as this generated code fails in typescript:

declare namespace Services {
  type Type = "ServiceType";
}
declare class Services {}
declare class Client {}
declare namespace Client {
  export import Services = Services;
}
export { Client };

@skaneprime
Copy link
Author

skaneprime commented Aug 2, 2021

@Swatinem If it flattens all imports then is there a way to redeclare a namaspace?

// Child.ts
export namespace Child {
    export type SomeType = 'Something'
}
// Main.ts
import { Child as ChildTemp } from './Child.ts'
export namespace Main {
     export import Child = ChildTemp
}

@Swatinem
Copy link
Owner

Swatinem commented Aug 5, 2021

Maybe there is, but I doubt its worth the effort.

@Danielku15
Copy link

I was about to file a similar issue and during my tests I even found a simpler scenario without namespaces not being supported. Am I right with my assumption that these problems relate I guess solving the following issue, should also fix the exports within namespaces:

// test.d.ts
export declare class Test {}
// input.d.ts
  import * as _Test from './test';
  export import Test = _Test.Test;

Will lead to:

input.d.ts → output.d.ts...[!] (plugin dts) Error: ImportEquals should have a literal source.

  1 | import * as _Test from 'test';
> 2 | export import Test = _Test.Test;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Rollup already seems to have some renaming mechanism in case we have name clashes:

// test.d.ts and test2.d.ts
export declare class Test {}
// input.d.ts
import * as _Test from './test';
import * as _Test2 from './test2';

export declare const fakeNS: {
    Test: typeof _Test.Test;
    Test2: typeof _Test2.Test;
};
// output.d.ts
declare class Test$1 {}

declare class Test {}

declare const fakeNS: {
    Test: typeof Test$1;
    Test2: typeof Test;
};

export { fakeNS };

If we can "activate" it somehow that the name of the export is already taken, there will happen a renaming and we can generate this:

// test.d.ts
export declare class Test {}
// input.d.ts
import * as _Test from './test';
export import Test = _Test.Test;
// output.d.ts
declare class Test$1 { }
export import Test = Test$1;

This would then also work if we have the export import within namespaces.

@Swatinem Swatinem added the wontfix This will not be worked on label Dec 24, 2021
@IanVS
Copy link

IanVS commented Nov 3, 2022

I hit this issue from source-map-js, which has a .d.ts file including:

declare module 'source-map-js/lib/source-map-generator' {
    import { SourceMapGenerator } from 'source-map-js'
    export { SourceMapGenerator }
}

And this throws the error mentioned above. Is there any workaround to this? I see the wontfix label. But I'm pretty lost on how to move forward.

@theajack
Copy link

Why this wontfix

@SpookyJelly
Copy link

Still got this on 2023. why the hack this won't fix?

@hyrious
Copy link
Contributor

hyrious commented Jul 7, 2023

Svelte 4's new d.ts file could hit this issue.

https://hyrious.me/npm-browser/[email protected]/package/types/index.d.ts:276

declare module 'svelte/compiler' {
	import type { AssignmentExpression, Node, Program } from 'estree';
	import type { SourceMap } from 'magic-string';
...

@josdejong
Copy link

I'm hitting this issue with Svelte 4 now, like @hyrious points out:

[!] (plugin dts) Error: namespace child (hoisting) not supported yet

  274 |
  275 | declare module 'svelte/compiler' {
> 276 |         import type { AssignmentExpression, Node, Program } from 'estree';
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  277 |         import type { SourceMap } from 'magic-string';
  278 |         export { walk as walk } from 'estree-walker';
  279 |         interface BaseNode {
node_modules/svelte/types/index.d.ts

Is there a solution for this?

@ryanbas21
Copy link

I'm hitting this issue with Svelte 4 now, like @hyrious points out:

[!] (plugin dts) Error: namespace child (hoisting) not supported yet

  274 |
  275 | declare module 'svelte/compiler' {
> 276 |         import type { AssignmentExpression, Node, Program } from 'estree';
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  277 |         import type { SourceMap } from 'magic-string';
  278 |         export { walk as walk } from 'estree-walker';
  279 |         interface BaseNode {
node_modules/svelte/types/index.d.ts

Is there a solution for this?

Did you solve this? it seems like you did

@josdejong
Copy link

josdejong commented Sep 1, 2023

@ryanbas21 basically:

  • With Svelte 3 I provided an vanilla JS UMD bundle and types bundle that had all external dependencies included, so the npm package has zero dependencies. I had dts configured with respectExternal: true to do that.
  • With Svelte 4, I configured dts with respectExternal: false (the default). So the types bundle does not include the types of external dependencies. The (vanilla js) npm package now has Svelte and a couple other external dependencies just for the sake of using their TypeScript types.

It feels a bit like a waste adding dependencies just for their types, but on the other hand, it is also neat not to publish duplicated types. I've seen some npm packages starting to publish their TypeScript types in a separate package, that may be a good idea.

@eXory2024
Copy link

I'm having the same issue because I'm importing typescript types like so:

import type {CompilerHost} from "typescript"

Will lead to (with respectExternals: true):

[!] (plugin dts) Error: namespace child (hoisting) not supported yet

  17 |     namespace server {
  18 |         namespace protocol {
> 19 |             export import ApplicableRefactorInfo = ts.ApplicableRefactorInfo;
     |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  20 |             export import ClassificationType = ts.ClassificationType;
  21 |             export import CompletionsTriggerCharacter = ts.CompletionsTriggerCharacter;
  22 |             export import CompletionTriggerKind = ts.CompletionTriggerKind;
node_modules/typescript/lib/typescript.d.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

10 participants