Typescript: Support ES `export * as ns from` form

Created on 16 Sep 2015  ·  33Comments  ·  Source: microsoft/TypeScript

The ES7 proposal is available at: https://github.com/leebyron/ecmascript-more-export-from

The additions include:

reexporting default:

// proposed:
export v from "mod";

// symmetric to:
import v from "mod";
export {v};

reexporting as sub-module:

// proposed:
export * as ns from "mod";

// symmetric to:
import * as ns from "mod";
export {ns};

also allowing combining

// proposed
export v, {x, y as w} from "mod"
// symmetric to
import v, {x, y as w} from "mod"
As well as

// proposed
export v, * as ns from "mod"
// symmetric to
import v, * as ns from "mod"
Committed ES Next Fixed Suggestion

Most helpful comment

9906 tracked the proposed export default from ( https://github.com/tc39/proposal-export-default-from ) and was marked as a duplicate of this

Adding this comment to make sure the request for supporting export default from isn't potentially overlooked as part of this issue

All 33 comments

:+1:

This would be incredibly helpful for supporting intellisense for JavaScript projects in VS Code; export * as foo from './foo'; seems pretty widely used

At first I thought this (the ECMAScript proposal) was a bad idea because the preponderance of existing export forms is a source of confusion for newcomers. However, I've come around to the idea that the asymmetry between the import and export forms is actually a source of confusion in itself so adding this would be beneficial.

Is there any chance of this being added sometime soon? I've been using this feature in my codebase with the stage-1 babel preset, and was hoping to start using typescript to get gradually get some static typechecking, but typescript throws a bunch of errors every time it comes across export x from './y';

Our team's projects usually has a common file for developers to import common things from, without having to worry about where they come from:

import {
  React,
  PropTypes,
  PureComponent,
  Button,
  connect,
} from './common'

Without export from, this common file will double in size and have needless duplication and some lines that can be confusing to newcomers.

// This ...
export React, {
  PureComponent,
  PropTypes,
} from 'react'

// ... becomes ...
import * as _React from 'react'
export const React = _React
export const PropTypes = _React.PropTypes
export const PureComponent = _React.PureComponent

Even more strange that export { connect } from 'react-redux' works.

You can do:

export { default as React, PureComponent, PropTypes, } from 'react'

On Wed, May 10, 2017, 11:32 mikew notifications@github.com wrote:

Even more strange that export { connect } from 'react-redux' works.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/Microsoft/TypeScript/issues/4813#issuecomment-300573386,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAChnZzvzQc10WXj9VkLM1HGl7B_D5Ulks5r4gLCgaJpZM4F-BqL
.

Almost, except then it's module "@types/react/index" has no exported member 'default'.

@mikew That is true but the same issue would apply to the proposed

export React, {
  PureComponent,
  PropTypes,
} from 'react';

The default issue is a complex issue stemming from a convoluted set of incompatibilities and disparate assumptions made by standards, languages, environments, loaders, bundlers, runtimes, and transpilers.

However, it is entirely orthogonal to this proposal.

If you can write

import React from 'react';

and it works at _runtime_, set the --allowSyntheticDefaultImports flag.

9906 tracked the proposed export default from ( https://github.com/tc39/proposal-export-default-from ) and was marked as a duplicate of this

Adding this comment to make sure the request for supporting export default from isn't potentially overlooked as part of this issue

Is this on the roadmap or we have to wait until the proposal reaches a certain stage?

Is this on the roadmap or we have to wait until the proposal reaches a certain stage?

IIRC, they tend to be taken on a case by case basis. Pre Stage 3 tend to get implemented under a flag, and only if they are important enough. Stage 3s tend to get implemented without flags.

Is this still not supported? Or is there a setting I am missing in jsconfig?

This spec has been withdrawn in favor of the equivalent micro-proposals: export ns from and export default from.

https://github.com/tc39/proposal-export-default-from
https://github.com/tc39/proposal-export-ns-from
They are both stage 1 now, usually, typescript will not support them until they are in stage 3.

proposal-export-ns-from is being PR'd into the language spec https://github.com/tc39/ecma262/pull/1005, assuming consensus, which makes it official. I don't understanding the how/why it's bypassing the staging process, but apparently it is.

Any plans to get this implemented into TypeScript?

Once the proposal makes it to stage 3, we will add support for it.

OK, so if it's not listed in https://github.com/tc39/proposals at all (source of truth for stages), yet it's being PR'd into the language spec (https://github.com/tc39/ecma262/pull/1005) pending consensus (conceptually, but not technically stage 4), what stage is it right now?

Sorry, I'm just not sure what this is considered, and how this fits into the stage 3 policy. Trying to get some understanding of what's going on.

There's also https://github.com/babel/proposals/issues/16, which marks it as "Needs Consensus PR", which before today was listed as "Stage 4", which I'm told is semi-sorta the same thing, but not really unless it's merged.

@bterlson what stage is this proposal in at the moment?

I'd like to add that this form should also be supported if not already covered.

export { default } from 'some-module'

This is the form that create-react-app apps accepts.

@rclai this should be already supported. ‘export default form “mod”’ is not.

I have a

// SomeComponent.js 
export default function SomeComponent() {
  return null
}

// index.js
export { default } from './SomeComponent'

When I import this from another place

import SomeComponent from 'components/SomeComponents'

The autocomplete works, but Cmd clicking on the import declaration variable or path doesn't take me to the SomeComponent.js and peeking doesn't work on it.

Am I missing some config or is this a separate issue?

My jsconfig.js

{
  "compilerOptions": {
    "target": "es2015",
    "baseUrl": "./src",
    "paths": {
      "components/*": ["./components/**/*"]
    }
  }
}

Sorry my bad. I read it as ‘export { default as foo} from “mod”’.

Yes exporting the default is not supported yet

Any update on when this will make it in?

@aMoniker the proposal was broken into two. The export * as ns from "mod" is covered in a consensus PR at: https://github.com/tc39/ecma262/pull/1174 which still has not made it into the language specification. Until that happens, TypeScript won't consider implementing it, though it is already shipping in most browsers.

The other part of the syntax, export v from "mod" is still a Stage 1 proposal: https://github.com/tc39/proposal-export-default-from and the TypeScript team won't consider implementing it until it reaches Stage 3 (or is added also via a consensus PR).

export * as ns from "foo" was shipped in v8 7.2, meaning current node and chrome can technically support it in their modules implementations - the downlevel isn't hard (just rewrite into

import * as ns from "foo";
export { ns }

and feed down the transformer pipeline). This does imply a new module target that _doesn't_ downlevel it, though, which means a bump of the exnext module and the addition of es2019 modules - the exact timing is a little muddy, since AFAIK it's shipped in v8 even though the proposal is still stage 1.

cc @RyanCavanaugh so we're aware

export * as ns from "foo" was merged and is now officially part of the language https://github.com/tc39/ecma262/pull/1174

It probably should be preserved instead of downleveled in esnext / es2020 emits.


Tangentially, this syntax is useful because of a bug in webpack 4 (fixed in webpack 5). It treats export * as ns from ... differently from the downlevel form, and is no longer capable of "tree shaking" if it's written in the downlevel form.

Changed the title since there is currently no export default version of this.

It's still mis-titled because it's no longer "proposed"; it is _already_ in the spec 😉

I’ve now opened #35010 for the export default from form.

Thanks @kingwl!

Previously I liked using TS namespaces and declaration merging for creating FP-style modules, without needing the MyModule.T convention:

export type Foobar = { }

export namespace Foobar {
  export function doStuff(foobar: Foobar) { }
}
import { Foobar } from './Foobar'

Foobar.doStuff(fb)

Namespaces are not really the way to go any more, babel doesn't support them, they probably aren't tree-shakeable etc. But I was hoping that the export * as ns syntax could be used as a replacement, like this:

export type Foobar = import('./Foobar').Foobar

// Or:
// export type { Foobar } from './Foobar'

export * as Foobar from './Foobar'

This seems to pass the nightly compiler, but the compiler only knows that Foobar is re-exported as a type, not a value. It would be great if the compiler could merge them into a combined value & type like with namespaces.

@katis: I filed #36792 with the content of your comment above.

I'm closing this issue as it was fixed in #34903.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MartynasZilinskas picture MartynasZilinskas  ·  3Comments

Antony-Jones picture Antony-Jones  ·  3Comments

weswigham picture weswigham  ·  3Comments

seanzer picture seanzer  ·  3Comments

dlaberge picture dlaberge  ·  3Comments