Skip to content

Inconsistency with default value export and default type export #61626

Closed as not planned
@sdegutis

Description

@sdegutis

Acknowledgement

  • I acknowledge that issues using this template may be closed without further explanation at the maintainer's discretion.

Comment

For a while, I've been vendoring Monaco as ESM and getting around its fake ESM like so:

// monaco.d.ts

import * as monaco from 'monaco-editor'
export default monaco

// monaco.js

const base = location.origin + '/monaco/min/vs'

await new Promise(resolve => {
  const script = document.createElement('script')
  script.src = base + "/loader.js"
  script.onload = resolve
  document.head.append(script)
})

export default await new Promise(resolve => {
  require.config({ paths: { vs: base } })
  require(['vs/editor/editor.main'], resolve)
})

But having two files for this one module is starting to stick out like a sore thumb. So I tried combining them.

I've been trying for years to get this to be one file, and it almost works, if I just do this:

- export default await new Promise(resolve => {
+ export default await new Promise<typeof import('monaco-editor')>(resolve => {

This allows me to continue to import it as normal:

import monaco from './monaco.js'
monaco.createEditor(...)

But the moment I try to use any types, it complains:

monaco.languages.setMonarchTokensProvider(
  'typescript',
  tokenProvider as monaco.languages.IMonarchLanguage)
                // ^ Cannot find namespace 'monaco'.

I don't really understand namespaces at all (Monaco is the only project I'm aware of that uses them), but it seems to me that this error means that the default export from monaco-editor is both a type and a value, just like classes implicitly are.

Assuming that to be the case, I tried every possible combination of imports/exports in this file to get tsc to see that I am, in fact, exporting both the type and value of the default export of monaco-editor. Nothing works.

I've asked over on stackoverflow too and am hoping jcalz has an answer, but I wanted to post this question here while the details are fresh in my mind, just in case he doesn't, since I've been dealing with this one two-file situation for literally a few years, and I want to finally get it done with.

Does TypeScript have a way to declare that a default export is the default export of a namespace import? Is that really what this situation is, or am I misunderstanding what's happening? And if it is, and there's no way to do it, is it easy to add as a language feature? Or are there workarounds besides my two-file solution?

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions