Skip to content

No TS2323 duplicate export errors with namespaces? #48047

@tolmasky

Description

@tolmasky

Bug Report

I'm aware that namespaces don't seem to be super recommended, but I am curious whether this is a bug or intended behavior, as I can't find explicit mention of it anywhere, and almost identical behavior is enforced through other language means, however it does not overlap in every circumstance. Basically, I am curious if the intention is that the following code does not throw a TS2323: Cannot redeclare exported variable 'x'. error in namespaces, but does throw the error in the normal top-level-scope (as dictated by the ECMAScript standard of course):

namespace A
{
    export var x: number = 10; // no error
    export var x: number = 20; // no error
}

export var x: number = 10; // error: TS2323: Cannot redeclare exported variable 'x'.
export var x: number = 20; // error: TS2323: Cannot redeclare exported variable 'x'.

As I mentioned before, this is kind of an edge case, because in all other binding circumstances, it kind of doesn't matter that TS2323 isn't thrown, because the duplicate binding error will save you instead (either TS2451 or TS2393):

namespace A
{
    export let x: number = 10; // error: error TS2451: Cannot redeclare block-scoped variable 'x'.
    export let x: number = 20; // error: error TS2451: Cannot redeclare block-scoped variable 'x'.

    // Typescript appears to throw TS2393 regardless of whether alwaysStrict is on (and you drop the export),
    // and regardless of whether inside or outside of a namespace, meaning that "var scope" appears 
    // to be unreachable for functions, but perhaps I am mistaken and there is a way to trigger it. 
    export function y() { return 10; }  // error: TS2393: Duplicate function implementation.
    export function y() { return 10; } // error: TS2393: Duplicate function implementation.
}

As you can see, the above all throw errors that make TS2323 arguably "redundant" (in that the user isn't allowed to type that code either way, regardless of which error they are getting). However, at the top level, these do also throw TS2323. So while this question only seems to have practical consequences with regard to var-scope-declared variables, it does apply to every export.

One could of course argue that the treatment of vars follows normal javascript convention (and arguably CommonJS convention), and that TS2323 is specifically an ECMA-modules error, but there is some inconsistency in copy-pasting between the two (which of course, there is even without this, just in the fact that you can't do export { x } in a namespace, etc.).

If this is intended behavior would it be OK for me to submit a PR that highlights some of these differences with "ECMA" exports in the guidebook (if it is the case that that doesn't already exist and I just missed it).

🔎 Search Terms

namespaces, TS2323

🕗 Version & Regression Information

4.5.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions