mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 13:48:46 -05:00
Allow export default interface. Related to issue 3792. (#16040)
* Allow export default interface. Related to issue 3792. * Update exportDefaultAbstractClass test * Allow default export to be a non-value for lookup purposes * Add local usage to exportDefaultInterface test
This commit is contained in:
@@ -1240,12 +1240,12 @@ namespace ts {
|
||||
if (token() === SyntaxKind.ExportKeyword) {
|
||||
nextToken();
|
||||
if (token() === SyntaxKind.DefaultKeyword) {
|
||||
return lookAhead(nextTokenIsClassOrFunctionOrAsync);
|
||||
return lookAhead(nextTokenCanFollowDefaultKeyword);
|
||||
}
|
||||
return token() !== SyntaxKind.AsteriskToken && token() !== SyntaxKind.AsKeyword && token() !== SyntaxKind.OpenBraceToken && canFollowModifier();
|
||||
}
|
||||
if (token() === SyntaxKind.DefaultKeyword) {
|
||||
return nextTokenIsClassOrFunctionOrAsync();
|
||||
return nextTokenCanFollowDefaultKeyword();
|
||||
}
|
||||
if (token() === SyntaxKind.StaticKeyword) {
|
||||
nextToken();
|
||||
@@ -1267,9 +1267,10 @@ namespace ts {
|
||||
|| isLiteralPropertyName();
|
||||
}
|
||||
|
||||
function nextTokenIsClassOrFunctionOrAsync(): boolean {
|
||||
function nextTokenCanFollowDefaultKeyword(): boolean {
|
||||
nextToken();
|
||||
return token() === SyntaxKind.ClassKeyword || token() === SyntaxKind.FunctionKeyword ||
|
||||
token() === SyntaxKind.InterfaceKeyword ||
|
||||
(token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
|
||||
(token() === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine));
|
||||
}
|
||||
|
||||
@@ -3168,11 +3168,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getLocalSymbolForExportDefault(symbol: Symbol) {
|
||||
return isExportDefaultSymbol(symbol) ? symbol.valueDeclaration.localSymbol : undefined;
|
||||
return isExportDefaultSymbol(symbol) ? symbol.declarations[0].localSymbol : undefined;
|
||||
}
|
||||
|
||||
function isExportDefaultSymbol(symbol: Symbol): boolean {
|
||||
return symbol && symbol.valueDeclaration && hasModifier(symbol.valueDeclaration, ModifierFlags.Default);
|
||||
return symbol && length(symbol.declarations) > 0 && hasModifier(symbol.declarations[0], ModifierFlags.Default);
|
||||
}
|
||||
|
||||
/** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */
|
||||
|
||||
@@ -1,14 +1,29 @@
|
||||
//// [tests/cases/compiler/exportDefaultAbstractClass.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
export default abstract class A {}
|
||||
export default abstract class A { a: number; }
|
||||
|
||||
class B extends A {}
|
||||
new B().a.toExponential();
|
||||
|
||||
//// [b.ts]
|
||||
import A from './a'
|
||||
|
||||
import A from './a';
|
||||
|
||||
class C extends A {}
|
||||
new C().a.toExponential();
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var A = (function () {
|
||||
function A() {
|
||||
@@ -16,6 +31,33 @@ var A = (function () {
|
||||
return A;
|
||||
}());
|
||||
exports["default"] = A;
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return B;
|
||||
}(A));
|
||||
new B().a.toExponential();
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var a_1 = require("./a");
|
||||
var C = (function (_super) {
|
||||
__extends(C, _super);
|
||||
function C() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return C;
|
||||
}(a_1["default"]));
|
||||
new C().a.toExponential();
|
||||
|
||||
@@ -1,8 +1,31 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
export default abstract class A {}
|
||||
export default abstract class A { a: number; }
|
||||
>A : Symbol(A, Decl(a.ts, 0, 0))
|
||||
>a : Symbol(A.a, Decl(a.ts, 0, 33))
|
||||
|
||||
class B extends A {}
|
||||
>B : Symbol(B, Decl(a.ts, 0, 46))
|
||||
>A : Symbol(A, Decl(a.ts, 0, 0))
|
||||
|
||||
new B().a.toExponential();
|
||||
>new B().a.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
|
||||
>new B().a : Symbol(A.a, Decl(a.ts, 0, 33))
|
||||
>B : Symbol(B, Decl(a.ts, 0, 46))
|
||||
>a : Symbol(A.a, Decl(a.ts, 0, 33))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import A from './a'
|
||||
import A from './a';
|
||||
>A : Symbol(A, Decl(b.ts, 0, 6))
|
||||
|
||||
class C extends A {}
|
||||
>C : Symbol(C, Decl(b.ts, 0, 20))
|
||||
>A : Symbol(A, Decl(b.ts, 0, 6))
|
||||
|
||||
new C().a.toExponential();
|
||||
>new C().a.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
|
||||
>new C().a : Symbol(A.a, Decl(a.ts, 0, 33))
|
||||
>C : Symbol(C, Decl(b.ts, 0, 20))
|
||||
>a : Symbol(A.a, Decl(a.ts, 0, 33))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
|
||||
|
||||
|
||||
@@ -1,8 +1,35 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
export default abstract class A {}
|
||||
export default abstract class A { a: number; }
|
||||
>A : A
|
||||
>a : number
|
||||
|
||||
class B extends A {}
|
||||
>B : B
|
||||
>A : A
|
||||
|
||||
new B().a.toExponential();
|
||||
>new B().a.toExponential() : string
|
||||
>new B().a.toExponential : (fractionDigits?: number) => string
|
||||
>new B().a : number
|
||||
>new B() : B
|
||||
>B : typeof B
|
||||
>a : number
|
||||
>toExponential : (fractionDigits?: number) => string
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import A from './a'
|
||||
import A from './a';
|
||||
>A : typeof A
|
||||
|
||||
class C extends A {}
|
||||
>C : C
|
||||
>A : A
|
||||
|
||||
new C().a.toExponential();
|
||||
>new C().a.toExponential() : string
|
||||
>new C().a.toExponential : (fractionDigits?: number) => string
|
||||
>new C().a : number
|
||||
>new C() : C
|
||||
>C : typeof C
|
||||
>a : number
|
||||
>toExponential : (fractionDigits?: number) => string
|
||||
|
||||
|
||||
24
tests/baselines/reference/exportDefaultInterface.js
Normal file
24
tests/baselines/reference/exportDefaultInterface.js
Normal file
@@ -0,0 +1,24 @@
|
||||
//// [tests/cases/compiler/exportDefaultInterface.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
export default interface A { value: number; }
|
||||
|
||||
var a: A;
|
||||
a.value.toExponential();
|
||||
|
||||
//// [b.ts]
|
||||
import A from './a';
|
||||
|
||||
var a: A;
|
||||
a.value.toExponential();
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var a;
|
||||
a.value.toExponential();
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var a;
|
||||
a.value.toExponential();
|
||||
31
tests/baselines/reference/exportDefaultInterface.symbols
Normal file
31
tests/baselines/reference/exportDefaultInterface.symbols
Normal file
@@ -0,0 +1,31 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
export default interface A { value: number; }
|
||||
>A : Symbol(A, Decl(a.ts, 0, 0))
|
||||
>value : Symbol(A.value, Decl(a.ts, 0, 28))
|
||||
|
||||
var a: A;
|
||||
>a : Symbol(a, Decl(a.ts, 2, 3))
|
||||
>A : Symbol(A, Decl(a.ts, 0, 0))
|
||||
|
||||
a.value.toExponential();
|
||||
>a.value.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
|
||||
>a.value : Symbol(A.value, Decl(a.ts, 0, 28))
|
||||
>a : Symbol(a, Decl(a.ts, 2, 3))
|
||||
>value : Symbol(A.value, Decl(a.ts, 0, 28))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import A from './a';
|
||||
>A : Symbol(A, Decl(b.ts, 0, 6))
|
||||
|
||||
var a: A;
|
||||
>a : Symbol(a, Decl(b.ts, 2, 3))
|
||||
>A : Symbol(A, Decl(b.ts, 0, 6))
|
||||
|
||||
a.value.toExponential();
|
||||
>a.value.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
|
||||
>a.value : Symbol(A.value, Decl(a.ts, 0, 28))
|
||||
>a : Symbol(a, Decl(b.ts, 2, 3))
|
||||
>value : Symbol(A.value, Decl(a.ts, 0, 28))
|
||||
>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --))
|
||||
|
||||
33
tests/baselines/reference/exportDefaultInterface.types
Normal file
33
tests/baselines/reference/exportDefaultInterface.types
Normal file
@@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
export default interface A { value: number; }
|
||||
>A : A
|
||||
>value : number
|
||||
|
||||
var a: A;
|
||||
>a : A
|
||||
>A : A
|
||||
|
||||
a.value.toExponential();
|
||||
>a.value.toExponential() : string
|
||||
>a.value.toExponential : (fractionDigits?: number) => string
|
||||
>a.value : number
|
||||
>a : A
|
||||
>value : number
|
||||
>toExponential : (fractionDigits?: number) => string
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import A from './a';
|
||||
>A : any
|
||||
|
||||
var a: A;
|
||||
>a : A
|
||||
>A : A
|
||||
|
||||
a.value.toExponential();
|
||||
>a.value.toExponential() : string
|
||||
>a.value.toExponential : (fractionDigits?: number) => string
|
||||
>a.value : number
|
||||
>a : A
|
||||
>value : number
|
||||
>toExponential : (fractionDigits?: number) => string
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
// @filename: a.ts
|
||||
export default abstract class A {}
|
||||
|
||||
// @filename: b.ts
|
||||
import A from './a'
|
||||
// @Filename: a.ts
|
||||
export default abstract class A { a: number; }
|
||||
|
||||
class B extends A {}
|
||||
new B().a.toExponential();
|
||||
|
||||
// @Filename: b.ts
|
||||
import A from './a';
|
||||
|
||||
class C extends A {}
|
||||
new C().a.toExponential();
|
||||
11
tests/cases/compiler/exportDefaultInterface.ts
Normal file
11
tests/cases/compiler/exportDefaultInterface.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
// @Filename: a.ts
|
||||
export default interface A { value: number; }
|
||||
|
||||
var a: A;
|
||||
a.value.toExponential();
|
||||
|
||||
// @Filename: b.ts
|
||||
import A from './a';
|
||||
|
||||
var a: A;
|
||||
a.value.toExponential();
|
||||
Reference in New Issue
Block a user