Skip to content

Export default of type emits invalid codeΒ #55087

Closed

Description

@EliLichtblau

Bug Report

πŸ”Ž Search Terms

Export default type
Export default type reference error

πŸ•— Version & Regression Information

This has always been the behavior

⏯ Playground Link

Playground link

πŸ’» Code

import type {SyntaxKind} from "typescript"

export default SyntaxKind

Emits ESM

export default SyntaxKind

Emits CommonJs

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = SyntaxKind;

which causes a reference error.

πŸ™ Actual behavior

Emitted code errors at runtime with reference error

πŸ™‚ Expected behavior

If I am default exporting a type I'd like that to be dropped from the emitted code as to not error.

Since this is old behavior I'm guessing this might have something to do with globals that I do not understand? Any clarification on the issue is also super appreciated.

Activity

  1. EliLichtblau commented on Jul 20, 2023

    @EliLichtblau
    ContributorAuthor
  2. fatcerberus commented on Jul 20, 2023

    @fatcerberus

    import type doesn't mean what you think it does: #54990 (comment)

    If there's a bug here, it's that the export default isn't being flagged as an error at compile time.

  3. EliLichtblau commented on Jul 20, 2023

    @EliLichtblau
    ContributorAuthor

    Thanks for the import type issue! I also agree that it should fail at compile time!

    I assumed it wasn't emitted at all - not sure if this is useful to the decision making process but essentially what "bit me" from this behavior was.

    Old codebase didn't properly annotate type imports and exports (as well importEqualsDeclaration use).
    (Sorry if annotate is the wrong word I should mean isTypeOnly=true on the import/export specifiers)
    I wrote a script to fix these cases.
    A file that used to be a module now only exported types so webpack dropped it - (at least this is my understanding).
    Code that used to say something like
    const webpack_default_export = (some_webpack_module.thingThatisType)
    became:
    const webpack_default_export = (thingThatisType)

    which is a reference error at runtime.

    I think this is the only weird edge case I missed - but I thought it was worth the bug report - thanks for the fast response and info again - really appreciate it!

  4. EliLichtblau commented on Jul 20, 2023

    @EliLichtblau
    ContributorAuthor

    Doubt this is wanted/will be accepted but here is the the change necessary to make this a compile time error
    (I went through the tests and ran my own test cases locally this seems to work as intended)

    else if (!node.isExportEquals && !(node.flags & NodeFlags.Ambient) && (getTypeOnlyAliasDeclaration(sym, undefined) || ((getAllSymbolFlags(sym) & SymbolFlags.Value) === 0))) {
              error(id, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, idText(id));
    }

    This would be added to checkExportAssignment at the time of writing on line 44685. This causes 21 test failures as this is a behavior change. Would you be open to a compiler flag - or perhaps adding this as an error to verbatim module syntax? Although I would personally prefer something like this as either a separate flag (verbatimModuleSyntax seems to have a lot of baggage) or as default behavior.

    Sorry if this is too intrusive!

  5. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions