Skip to content

Allow export default const enum, export default enum, export default … #18628

New issue

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

By clicking “No 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? No Sign in to your account

Conversation

NaridaL
Copy link
Contributor

@NaridaL NaridaL commented Sep 21, 2017

…declare class

Also export default namespace.

#3792 (comment)

@mhegazy what about export default type foo = {} ?

@NaridaL
Copy link
Contributor Author

NaridaL commented Sep 21, 2017

Hmm it seems to pass here, but I'm getting...?

PS C:\Users\aval\tsdev\TypeScript> npx gulp runtests-parallel
C:\Users\aval\tsdev\TypeScript\node_modules\gulp\bin\gulp.js
[03:01:04] Requiring external module ts-node/register
[03:01:04] Using gulpfile ~\tsdev\TypeScript\gulpfile.ts
[03:01:04] Starting 'build-rules'...
snip snip
[03:01:05] Finished 'built\local\run.js' after 232 ms
[03:01:05] Starting 'tests'...
[03:01:05] Finished 'tests' after 2.34 μs
[03:01:05] Starting 'runtests-parallel'...
Running tests with config: {"light":false,"workerCount":4,"taskConfigsFolder":"C:\\Users\\aval\\AppData\\Local\\Temp/ts-tests34","noColor":false}
node built\local\run.js
Discovering tests...
Discovered 11206 test files in 665ms.
Starting to run tests using 4 threads...
Batching initial test lists...
Suboptimal packing detected: no tests remain to be stolen. Reduce packing fraction from 0.9 to fix.
Batched into 3 groups. Unprofiled tests including tsrunner-compiler://tests/cases/compiler/exportDefaultNamespace.ts will be run first.

  [........................................................................................................................................................................]
Test worker encounted unexpected error and was forced to close:
        Message: Cannot read property 'runner' of undefined
        Stack: TypeError: Cannot read property 'runner' of undefined
    at process.<anonymous> (C:\Users\aval\tsdev\TypeScript\src\harness\parallel\worker.ts:143:29)
    at emitTwo (events.js:125:13)
    at process.emit (events.js:213:7)
    at process.emit (C:\Users\aval\tsdev\TypeScript\node_modules\source-map-support\source-map-support.js:431:21)
    at emit (internal/child_process.js:774:12)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
[03:01:09] 'runtests-parallel' errored after 4.47 s
[03:01:09] Error: 2
    at formatError (C:\Users\aval\tsdev\TypeScript\node_modules\gulp\bin\gulp.js:169:10)
    at Gulp.<anonymous> (C:\Users\aval\tsdev\TypeScript\node_modules\gulp\bin\gulp.js:195:15)
    at emitOne (events.js:115:13)
    at Gulp.emit (events.js:210:7)
    at Gulp.Orchestrator._emitTaskDone (C:\Users\aval\tsdev\TypeScript\node_modules\orchestrator\index.js:264:8)
    at C:\Users\aval\tsdev\TypeScript\node_modules\orchestrator\index.js:275:23
    at finish (C:\Users\aval\tsdev\TypeScript\node_modules\orchestrator\lib\runTask.js:21:8)
    at cb (C:\Users\aval\tsdev\TypeScript\node_modules\orchestrator\lib\runTask.js:29:3)
    at failWithStatus (C:\Users\aval\tsdev\TypeScript\gulpfile.ts:680:9)
    at C:\Users\aval\tsdev\TypeScript\gulpfile.ts:697:17
    at <anonymous>

@@ -1310,7 +1310,11 @@ namespace ts {
nextToken();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nextTokenCanFollowDefaultKeyword doesn't really seem like an accurate name considering it's looking at multiple? Same with nextTokenCanFollowModifier. Would something like declarationCanFollowExportDefault be more appropriate?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name is fine since it doesn't take a declaration as input, it just goes to the next token and looks at its kind and maybe does some minimal lookahead.

@k8w
Copy link

k8w commented Sep 25, 2017

export default const a = 'a';

Still get error in tsc 2.6.0-dev.20170921

@microsoft microsoft deleted a comment from msftclas Sep 27, 2017
@mhegazy mhegazy requested a review from a user November 8, 2017 17:57
@mhegazy
Copy link
Contributor

mhegazy commented Nov 8, 2017

@Andy-MS can you please review this change.. we need to make sure all LS features work as expected with this change..

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay

@@ -1310,7 +1310,11 @@ namespace ts {
nextToken();
return token() === SyntaxKind.ClassKeyword || token() === SyntaxKind.FunctionKeyword ||
token() === SyntaxKind.InterfaceKeyword ||
token() === SyntaxKind.EnumKeyword ||
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is big enough now to deserve a switch statement.

(token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
(token() === SyntaxKind.DeclareKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also test export default declare namespace

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we should probably allow the old module keyword here as equivalent with namespace for consistency.

Copy link
Contributor Author

@NaridaL NaridaL Dec 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about export default declare abstract class ?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that should be supported too.

var A;
(function (A) {
A[A["FOO"] = 0] = "FOO";
})(A = exports.A || (exports.A = {}));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like an emitter bug -- It should be writing to exports.default.

return 0xC0FFEE;
}
N.foo = foo;
})(N = exports.N || (exports.N = {}));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same emitter bug here -- should write to exports.default, not exports.N.

@NaridaL
Copy link
Contributor Author

NaridaL commented Jan 16, 2018

@k8w See https://esdiscuss.org/topic/why-is-export-default-var-a-1-invalid-syntax for why that doesn't make sense.

@NaridaL
Copy link
Contributor Author

NaridaL commented Jan 16, 2018

My turn to apologize for the delay; sorry.

I rewrote nextTokenCanFollowDefaultKeyword to use a switch statement.
Fixing the transformer is unfortunately not quite so simple.

Currently the enum transformer generates something like N = N || (N = {}), with the latter two N's then getting transformed into exports.N by the module transformer. Something like N = default || (default = {}) doesn't make much sense and doesn't get transformed correctly anyways. In any case this pattern isn't transferable for ES6 modules output.

In general, the behavior of ts.ts:visitEnumDeclaration (and visitModuleDeclaration) seems weird. Doing the || {} in the IIFE argument instead of in the initializer requires behavior conditional on the targeted module. (https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L2613-L2619)

The latest commit transforms as follows for ES6, with the further changes for commonjs etc being handled by the respective transformers.

export default enum A { FOO = 2 };
// should be transformed into
var A = A || {};
export default A;
(function (A) {
    A[A["FOO"] = 2] = "FOO";
})(A);


export enum A { FOO = 2 };
// should be transformed into
export var A = A || {};
(function (A) {
    A[A["FOO"] = 2] = "FOO";
})(A);



namespace ts {
	export enum A { FOO = 2 };
}
// should be transformed into
var ts = ts || {};
(function (ts) {
	var A = ts.A || {};
	ts.A = A;
	(function (A) {
    	A[A["FOO"] = 2] = "FOO";
	})(A);
})(ts);

It's very much possible I've missed some slight semantic difference...
This changes touches > 800 tests so I've only committed tests=/exportDefault.*/

I'd appreciate feedback on my approach before I clean up the remaining errors/problems.

"use strict";
exports.__esModule = true;
// https://github.com/Microsoft/TypeScript/issues/3792
var N = exports.N || {};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exports.N is a bit awkward here, but AFAIK should always be undefined, as things like the following aren't allowed?

export default class N {}
export class N {}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned above regarding enum, in this case N should only ever be a local binding inside the module. This should read:

var N = N || {};
exports["default"] = N;
(function (N) {
    function foo() {
        return 0xC0FFEE;
    }
    N.foo = foo;
})(N);

We also should consider allowing a "nameless" namespace:

// ts
export default namespace {
    export function foo() {
        return 0xC0FFEE;
    }
}

// js
var _a = {};
exports["default"] = _a;
(function (_a) {
    function foo() {
        return 0xC0FFEE;
    }
    _a.foo = foo;
})(_a);

// alternatively

exports["default"] = (function () {
    var _a = {};
    function foo() {
        return 0xC0FFEE;
    }
    _a.foo = foo;
    return _a;
})();

Copy link
Contributor Author

@NaridaL NaridaL Jan 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback, I'll get started on it. Would a nameless namespace be equivalent to a "namespace expression"? In any case I see some issues when module=es6:

export default namespace {
    export const a = 2;
}
// namespace merge
export default namespace {
    export const b = 2;
}

// requires generated variable name:
var _gen0 = {}
export default _gen0;
(function (_gen0) {
    _gen0.a = 2;
})(_gen0);
(function (_gen0) {
    _gen0.b = 2;
})(_gen0);

As anonymous interfaces aren't allowed either currently, maybe this would be better handled as a separate issue?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a fair point, and perhaps we should hold off on nameless enum/namespace for now until the team has had an opportunity to discuss. My intuition is that you would not be able to merge with a nameless default namespace.

@DanielRosenwasser, @mhegazy: any thoughts?

Copy link
Member

@rbuckton rbuckton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address the above feedback and add tests for this emit output in the following contexts:

  • --target es5 --module commonjs
  • --target es5 --module amd
  • --target es5 --module system
  • --target es5 --module es2015
  • --target es2015 --module commonjs
  • --target es2015 --module amd
  • --target es2015 --module system
  • --target es2015 --module es2015

Also please add tests that verify declaration file (.d.ts) output.

return lookAhead(nextTokenIsClassKeywordOnSameLine);
case SyntaxKind.DeclareKeyword:
// "export default declare class" and "export default declare abstract class" are both valid
return lookAhead(nextTokenIsClassKeywordOnSameLine) || lookAhead(nextTokenIsAbstractKeywordOnSameLine);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lookahead is not free, so I would recommend combining the two operations into a single lookahead. Also, you really want to do 2 token lookahead here for abstract:

  • default declare class - OK
  • default declare abstract - Not OK (especially if its followed by function, etc.)
  • default declare abstract class - OK

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about these:

  • default declare function
  • default declare async function (this syntax is invalid, however we report a more detailed error during grammar check)
  • default declare namespace
  • default declare module
  • default declare enum
  • default declare const enum

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClassDeclaration and FunctionDeclaration exported as default can elide the declaration name. Are we intending to support that for InterfaceDeclaration, EnumDeclaration, and ModuleDeclaration as well?

&& moduleKind !== ModuleKind.ESNext
&& moduleKind !== ModuleKind.System);
}
// function hasNamespaceQualifiedExportName(node: Node) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid commented code.

"use strict";
exports.__esModule = true;
// https://github.com/Microsoft/TypeScript/issues/3792
var A = exports.A || {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we intend for enum to work similar to class and function, then this is not the correct emit. Here you are exporting A as both A and default, where for a class or function it only exports default while the declaration name is a local binding only within the module.

With your new proposed emit this should instead be:

var A = A || {};
exports["default"] = A;
(function (A) {
    A[A["FOO"] = 0] = "FOO";
})(A);

If we plan to allow elision of the enum name (like you can with ES6 classes and functions), then you might emit:

// ts
export default enum {
  FOO = 1;
}

// js
var _a = {};
exports["default"] = _a;
(function (_a) {
    _a[_a["FOO"] = 0] = "FOO";
})(_a);

// or, alternatively:
exports["default"] = (function () {
  var _a = {};
  _a[_a["FOO"] = 0] = "FOO";
  return _a;
})();

"use strict";
exports.__esModule = true;
// https://github.com/Microsoft/TypeScript/issues/3792
var N = exports.N || {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned above regarding enum, in this case N should only ever be a local binding inside the module. This should read:

var N = N || {};
exports["default"] = N;
(function (N) {
    function foo() {
        return 0xC0FFEE;
    }
    N.foo = foo;
})(N);

We also should consider allowing a "nameless" namespace:

// ts
export default namespace {
    export function foo() {
        return 0xC0FFEE;
    }
}

// js
var _a = {};
exports["default"] = _a;
(function (_a) {
    function foo() {
        return 0xC0FFEE;
    }
    _a.foo = foo;
})(_a);

// alternatively

exports["default"] = (function () {
    var _a = {};
    function foo() {
        return 0xC0FFEE;
    }
    _a.foo = foo;
    return _a;
})();

@mhegazy
Copy link
Contributor

mhegazy commented Jan 18, 2018

I think we need to discuss the nameless declarations in the design meeting first.

@NaridaL NaridaL force-pushed the exportdefault_constenum_enum_declareclass branch from 29a8fad to a0e3747 Compare January 20, 2018 21:32
@NaridaL
Copy link
Contributor Author

NaridaL commented Jan 20, 2018

I've overwritten the previous commits with two new ones. The first one includes all new tests and changes to parser.ts. The changed files are limited to the new tests and 2 others. The second commit changes the emit in ts.ts, which results in a lot of changed test results. I've closely reviewed the changes in my new tests and looked at a couple of the others at random.

There's still a weird exception for outputting comments when in system module in ts.ts. https://github.com/Microsoft/TypeScript/pull/18628/files#diff-c0d0e8b1528663b6cff3bb893150cec3R2873 This seems like it would better be properly handled in transformers/system.ts

I had to change my proposed transform slightly:

export enum A { FOO = 2 };
// should be transformed into
export var A = A || {};
(function (A) {
    A[A["FOO"] = 2] = "FOO";
})(A);
const usage = A.FOO

the above doesn't work, because binder.ts creates both an export and a local symbol for the enum, and the A in usage points to the local symbol. With module=es6 this ends as:

exports.A = {}
(function (A) {
    A[A["FOO"] = 2] = "FOO";
})(A);
const usage = A.FOO // breaks because no local is defined.

Forcing it to always use the exported version on emit breaks for export default, where it uses the non-existent "exports.A". As far as I can tell, changing this would require significant changes in the binder so that export enum A behaves likes export var A.

Current ES2015 output (which is correctly transformed by the following transformers):

const A = {};
export { A };
(function (A) {
    A[A["FOO"] = 2] = "FOO";
})(A);
const usage = A.FOO

On topic, why are some transformations delayed until onEmit? I couldn't find any hint in the source.

case SyntaxKind.DeclareKeyword:
case SyntaxKind.AsyncKeyword:
case SyntaxKind.TypeKeyword:
return lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rbuckton This simplified lookahead seems to be enough; see 5113249#diff-cc2127059a7624c4bd840e11d106cb81

}
return token() !== SyntaxKind.AsteriskToken && token() !== SyntaxKind.AsKeyword && token() !== SyntaxKind.OpenBraceToken && canFollowModifier();
}
if (token() === SyntaxKind.DefaultKeyword) {
return nextTokenCanFollowDefaultKeyword();
return nextTokenCanFollowDefaultModifier();
Copy link
Contributor Author

@NaridaL NaridaL Jan 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole parseModifiers method is very confusing...

node.localSymbol = local;
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I flipped these two lines so I can access node.localSymbol in declareSymbol so can check if two default exports do not have the same identifier. Maybe this is better handled in checker.ts?

"namespace.ts",
"type.ts"
]
}
Copy link
Contributor Author

@NaridaL NaridaL Jan 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this project test to test the .d.ts output, is there a better way? Can I suppress the .js output?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are trying to avoid adding new "projects" tests in favor test variations in compiler/conformance tests. You can set // @declaration: true in the compiler/conformance tests to get .d.ts output.

// declaration we do not emit a leading variable declaration. To preserve the
// begin/end semantics of the declararation and to properly handle exports
// we wrap the leading variable declaration in a `MergeDeclarationMarker`.
const mergeMarker = createMergeDeclarationMarker(statement);
Copy link
Contributor Author

@NaridaL NaridaL Jan 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MergeDeclarationMarker are unnecessary if the variable is initialized immediately. I think the logic handling those in the other locations is now dead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any other places that still create a MergeDeclarationMarker? If not are we able remove it completely from types.ts/factory.ts?

@typescript-bot
Copy link
Collaborator

Thanks for your contribution. This PR has not been updated in a while and cannot be automatically merged at the time being. For housekeeping purposes we are closing stale PRs. If you'd still like to continue working on this PR, please leave a message and one of the maintainers can reopen it.

@alvis
Copy link

alvis commented Jun 14, 2018

ping @Andy-MS & @rbuckton

@ghost ghost reopened this Jun 14, 2018
@NaridaL
Copy link
Contributor Author

NaridaL commented Jun 19, 2018

If someone OKs my proposed transform above I can rebase this (assuming there's still interest).

@alvis
Copy link

alvis commented Jun 19, 2018

Yes. There're still people, like me, waiting for it being merged.

@codetalks-new
Copy link

If I export default a const enum, it will eventually produce undefined value.

const enum  Status{
   good = 0,
   bad = -1
}
export default Status; // this can lead undefined error. when using as `Status.good`

@NaridaL
Copy link
Contributor Author

NaridaL commented Jul 19, 2018

@banxi1988 I don't follow...?

@codetalks-new
Copy link

codetalks-new commented Jul 20, 2018

@NaridaL sorry, I do actually encountered the undefined error caused by export default const enum type in my project. but Haven't reproduce it in a demo project. I'll try to reproduce it with a webpack configured project.

@RyanCavanaugh
Copy link
Member

@NaridaL if you can get this merged up with master we can give it a fresh review. Thanks for your patience!

@RyanCavanaugh RyanCavanaugh added this to the Community milestone Sep 17, 2018
…icrosoft#3792 (comment).

Added corresponding tests.
NB: export defaults are not yet transformed correctly.
@NaridaL NaridaL force-pushed the exportdefault_constenum_enum_declareclass branch from a0e3747 to cdc7090 Compare September 23, 2018 12:41
@NaridaL NaridaL force-pushed the exportdefault_constenum_enum_declareclass branch from cdc7090 to 59c39e2 Compare September 23, 2018 20:43
@NaridaL
Copy link
Contributor Author

NaridaL commented Sep 23, 2018

Rebased it...

In: tests/baselines/reference/transformApi/transformsCorrectly.transformAddCommentToNamespace.js

The comment is being output both on the var declaration and the module statement.

Could someone please clarify what the difference between an emit node and a synthesized node and when/why they should be used? Setting a flag or comment range is clearly the cause of the above issue, but it's not obvious where... it works fine in the tests I added.

@rbuckton
Copy link
Member

rbuckton commented Feb 6, 2019

EmitNode is not an actual AST node, but rather is an extra set of properties attached to a Node that effects emit. These properties aren't added to a Node directly as it would increase the memory requirements for Node in the language service, which rarely needs to perform emit.

A "synthesized" node is a Node that was created synthetically as part of a transformation rather than created by the parser "from source". A "synthesized" node has NodeFlags.Synthesized in its flags property, and usually has a pos and end of -1 (although these can be set to actual positions if the synthesized node corresponds to an actual node.

@rbuckton
Copy link
Member

rbuckton commented Feb 6, 2019

If you set pos or end on a synthesized Node (i.e. via the setTextRange function), it will use those positions for comment emit. You can disable this by setting an EmitFlag of NoComments via the setEmitFlag function.

Copy link
Member

@rbuckton rbuckton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a number of errors in the various module-specific emit tests that need to be addressed.

setTextRange(enumStatement, node);
setCommentRange(enumStatement, node);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't be necessary to set the comment range if you've also set the text range. Setting the text range sets the pos and end of enumStatement to be that of node, which affects both comment emit and source map emit. Setting the comment range should be redundant.

addEmitFlags(enumStatement, emitFlags);
statements.push(enumStatement);

// Add a DeclarationMarker for the enum to preserve trailing comments and mark
// the end of the declaration.
statements.push(createEndOfDeclarationMarker(node));
// statements.push(createEndOfDeclarationMarker(node));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we no longer need the end-of-declaration marker node? It's used to handled deferred exports for ES2015, CommonJS, AMD, and SystemJS. If we no longer need it I would remove this line rather than just comment it.


// (function (x) {
// x[x["y"] = 0] = "y";
// ...
// })(x || (x = {}));
// })(x);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to make this change to emit behavior conditional on when it is necessary rather than always emit this way? It would significantly reduce the number of test changes in the PR.

// declaration we do not emit a leading variable declaration. To preserve the
// begin/end semantics of the declararation and to properly handle exports
// we wrap the leading variable declaration in a `MergeDeclarationMarker`.
const mergeMarker = createMergeDeclarationMarker(statement);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any other places that still create a MergeDeclarationMarker? If not are we able remove it completely from types.ts/factory.ts?

@@ -4101,7 +4126,7 @@ namespace ts {

sourceFile.flags |= NodeFlags.PossiblyContainsImportMeta;
}
else {
else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation here is wrong.

/**
* namespace B 1 leading comment
*/
var B = {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

B is never exported, despite the fact it is declared as export enum B in the test.

@@ -0,0 +1,62 @@
// https://github.com/Microsoft/TypeScript/issues/3792
// @target: es2015
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our compiler runner supports test variations for the same source. Instead of multiple nnnTargetXModuleY.ts files you can do this instead:

Suggested change
// @target: es2015
// @target: es2015, es5

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be nice, but it doesn't look like it's in yet?

Error: Unknown value 'es5, es2015' for compiler option 'target'.

@@ -0,0 +1,62 @@
// https://github.com/Microsoft/TypeScript/issues/3792
// @target: es2015
// @module: amd
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our compiler runner supports test variations for the same source. Instead of multiple nnnTargetXModuleY.ts files you can do this instead:

Suggested change
// @module: amd
// @module: amd, commonjs, system, es2015

@@ -0,0 +1,62 @@
// https://github.com/Microsoft/TypeScript/issues/3792
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding these tests in a relevant location under tests/cases/conformance/** as tests/cases/compiler is extremely cluttered and unorganized.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, consider adding // @declaration: true to verify .d.ts emit and // @sourceMaps: true to verify source-map emit.

"namespace.ts",
"type.ts"
]
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are trying to avoid adding new "projects" tests in favor test variations in compiler/conformance tests. You can set // @declaration: true in the compiler/conformance tests to get .d.ts output.

@TomasHubelbauer
Copy link

Sorry for a dumb question, but does this add support for export default type? The diff is more than 1k files so I haven't really tried to figure that out from the changes.

@RyanCavanaugh
Copy link
Member

Closing due to lack of activity here. Thanks for the work so far - if anyone would like to pick up on this feature, please do!

@TomasHubelbauer
Copy link

Is there an "authoritative" issue for people to subscribe to in order to be kept in the loop on this feature eventually dropping? This PR doesn't reference any issues as far as I can see and searching for export default and export default type returns 50 pages of results.

resolritter added a commit to resolritter/tree-sitter-typescript that referenced this pull request Dec 15, 2020
covers
- "[abstract] class"
- interfaces
as per microsoft/TypeScript#3792 (comment) in 2020/12/15

other constructs (microsoft/TypeScript#18628 (comment)) are not yet supported by TypeScript itself
resolritter added a commit to resolritter/tree-sitter-typescript that referenced this pull request Dec 15, 2020
covers
- "[abstract] class"
- interfaces
as per microsoft/TypeScript#3792 (comment) in 2020/12/15

other constructs (microsoft/TypeScript#18628 (comment)) are not yet supported by TypeScript itself
resolritter added a commit to resolritter/tree-sitter-typescript that referenced this pull request Dec 15, 2020
covers
- "[abstract] class"
- interfaces
as per microsoft/TypeScript#3792 (comment) in 2020/12/15

other constructs (microsoft/TypeScript#18628 (comment)) are not yet supported by TypeScript itself
resolritter added a commit to resolritter/tree-sitter-typescript that referenced this pull request Jan 29, 2021
covers
- "[abstract] class"
- interfaces
as per microsoft/TypeScript#3792 (comment) in 2020/12/15

other constructs (microsoft/TypeScript#18628 (comment)) are not yet supported by TypeScript itself
resolritter added a commit to resolritter/tree-sitter-typescript that referenced this pull request Mar 2, 2021
covers
- "[abstract] class"
- interfaces
as per microsoft/TypeScript#3792 (comment) in 2020/12/15

other constructs (microsoft/TypeScript#18628 (comment)) are not yet supported by TypeScript itself
@damianobarbati
Copy link

@NaridaL why was this closed? Is there any chance of having export default type {}?

No Sign up for free to join this conversation on GitHub. Already have an account? No Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.