Support js nested namespace decls on exports
and module.exports.
This commit is contained in:
parent
4099d48ea5
commit
c3143d2e47
|
@ -2303,7 +2303,17 @@ namespace ts {
|
|||
// When we create a property via 'exports.foo = bar', the 'exports.foo' property access
|
||||
// expression is the declaration
|
||||
setCommonJsModuleIndicator(node);
|
||||
declareSymbol(file.symbol.exports, file.symbol, <PropertyAccessExpression>node.left, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None);
|
||||
const lhs = node.left as PropertyAccessEntityNameExpression;
|
||||
const symbol = forEachIdentifierInEntityName(lhs.expression, (id, original, e) => {
|
||||
if (isExportsOrModuleExportsOrAlias(file, e) || (isIdentifier(e) && e.escapedText === "module" && original === undefined)) {
|
||||
return file.symbol;
|
||||
}
|
||||
Debug.assert(!!original);
|
||||
const s = getJSInitializerSymbol(original);
|
||||
addDeclarationToSymbol(s, id, SymbolFlags.Module | SymbolFlags.JSContainer);
|
||||
return s;
|
||||
});
|
||||
declareSymbol(symbol.exports, symbol, lhs, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None);
|
||||
}
|
||||
|
||||
function bindModuleExportsAssignment(node: BinaryExpression) {
|
||||
|
@ -2460,14 +2470,14 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function forEachIdentifierInEntityName(e: EntityNameExpression, action: (e: Identifier, symbol: Symbol) => Symbol): Symbol {
|
||||
function forEachIdentifierInEntityName(e: EntityNameExpression, action: (e: Identifier, symbol: Symbol, k: EntityNameExpression) => Symbol): Symbol {
|
||||
if (isIdentifier(e)) {
|
||||
return action(e, lookupSymbolForPropertyAccess(e));
|
||||
return action(e, lookupSymbolForPropertyAccess(e), e);
|
||||
}
|
||||
else {
|
||||
const s = getJSInitializerSymbol(forEachIdentifierInEntityName(e.expression, action));
|
||||
Debug.assert(!!s && !!s.exports);
|
||||
return action(e.name, s.exports.get(e.name.escapedText));
|
||||
return action(e.name, s.exports.get(e.name.escapedText), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1585,8 +1585,9 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkAndReportErrorForUsingTypeAsNamespace(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean {
|
||||
if (meaning === SymbolFlags.Namespace) {
|
||||
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Namespace, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
|
||||
const namespaceMeaning = SymbolFlags.Namespace | (isInJavaScriptFile(errorLocation) ? SymbolFlags.Value : 0);
|
||||
if (meaning === namespaceMeaning) {
|
||||
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~namespaceMeaning, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
|
||||
const parent = errorLocation.parent;
|
||||
if (symbol) {
|
||||
if (isQualifiedName(parent)) {
|
||||
|
@ -1992,9 +1993,10 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const namespaceMeaning = SymbolFlags.Namespace | (isInJavaScriptFile(name) ? meaning & SymbolFlags.Value : 0);
|
||||
let symbol: Symbol;
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
const message = meaning === SymbolFlags.Namespace ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0;
|
||||
const message = meaning === namespaceMeaning ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0;
|
||||
|
||||
symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors ? undefined : message, name, /*isUse*/ true);
|
||||
if (!symbol) {
|
||||
|
@ -2004,7 +2006,7 @@ namespace ts {
|
|||
else if (name.kind === SyntaxKind.QualifiedName || name.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
const left = name.kind === SyntaxKind.QualifiedName ? name.left : name.expression;
|
||||
const right = name.kind === SyntaxKind.QualifiedName ? name.right : name.name;
|
||||
let namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, /*dontResolveAlias*/ false, location);
|
||||
let namespace = resolveEntityName(left, namespaceMeaning, ignoreErrors, /*dontResolveAlias*/ false, location);
|
||||
if (!namespace || nodeIsMissing(right)) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -2012,7 +2014,7 @@ namespace ts {
|
|||
return namespace;
|
||||
}
|
||||
if (isInJavaScriptFile(name)) {
|
||||
const initializer = getDeclaredJavascriptInitializer(namespace.valueDeclaration);
|
||||
const initializer = getDeclaredJavascriptInitializer(namespace.valueDeclaration) || getAssignedJavascriptInitializer(namespace.valueDeclaration);
|
||||
if (initializer) {
|
||||
namespace = getSymbolOfNode(initializer);
|
||||
}
|
||||
|
|
|
@ -1488,7 +1488,8 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function getAssignedJavascriptInitializer(node: Node) {
|
||||
return (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.BarBarToken || isPropertyAccessExpression(node)) &&
|
||||
return node &&
|
||||
(isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.BarBarToken || isPropertyAccessExpression(node)) &&
|
||||
node.parent && isBinaryExpression(node.parent) &&
|
||||
node.parent.operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
(getJavascriptInitializer(node.parent.right) || getDefaultedJavascriptInitializer(node.parent.left as EntityNameExpression, node.parent.right));
|
||||
|
@ -1570,33 +1571,30 @@ namespace ts {
|
|||
if (lhs.expression.kind === SyntaxKind.ThisKeyword) {
|
||||
return SpecialPropertyAssignmentKind.ThisProperty;
|
||||
}
|
||||
if (isIdentifier(lhs.expression)) {
|
||||
if (lhs.expression.escapedText === "exports") {
|
||||
// exports.name = expr
|
||||
return SpecialPropertyAssignmentKind.ExportsProperty;
|
||||
}
|
||||
else if (lhs.expression.escapedText === "module" && lhs.name.escapedText === "exports") {
|
||||
// module.exports = expr
|
||||
return SpecialPropertyAssignmentKind.ModuleExports;
|
||||
}
|
||||
else if (isIdentifier(lhs.expression) && lhs.expression.escapedText === "module" && lhs.name.escapedText === "exports") {
|
||||
// module.exports = expr
|
||||
return SpecialPropertyAssignmentKind.ModuleExports;
|
||||
}
|
||||
if (isEntityNameExpression(lhs.expression)) {
|
||||
else if (isEntityNameExpression(lhs.expression)) {
|
||||
if (lhs.name.escapedText === "prototype" && isObjectLiteralExpression(expr.right)) {
|
||||
// F.prototype = { ... }
|
||||
return SpecialPropertyAssignmentKind.Prototype;
|
||||
}
|
||||
else if (isPropertyAccessExpression(lhs.expression)) {
|
||||
// chained dot, e.g. x.y.z = expr; this var is the 'x.y' part
|
||||
if (isIdentifier(lhs.expression.expression) &&
|
||||
lhs.expression.expression.escapedText === "module" &&
|
||||
lhs.expression.name.escapedText === "exports") {
|
||||
// module.exports.name = expr
|
||||
return SpecialPropertyAssignmentKind.ExportsProperty;
|
||||
}
|
||||
if (lhs.expression.name.escapedText === "prototype") {
|
||||
// F.G....prototype.x = expr
|
||||
return SpecialPropertyAssignmentKind.PrototypeProperty;
|
||||
}
|
||||
else if (isPropertyAccessExpression(lhs.expression) && lhs.expression.name.escapedText === "prototype") {
|
||||
// F.G....prototype.x = expr
|
||||
return SpecialPropertyAssignmentKind.PrototypeProperty;
|
||||
}
|
||||
|
||||
let nextToLast = lhs;
|
||||
while (isPropertyAccessExpression(nextToLast.expression)) {
|
||||
nextToLast = nextToLast.expression;
|
||||
}
|
||||
Debug.assert(isIdentifier(nextToLast.expression));
|
||||
const id = nextToLast.expression as Identifier;
|
||||
if (id.escapedText === "exports" ||
|
||||
id.escapedText === "module" && nextToLast.name.escapedText === "exports") {
|
||||
// exports.name = expr OR module.exports.name = expr
|
||||
return SpecialPropertyAssignmentKind.ExportsProperty;
|
||||
}
|
||||
// F.G...x = expr
|
||||
return SpecialPropertyAssignmentKind.Property;
|
||||
|
|
74
tests/baselines/reference/exportNestedNamespaces.symbols
Normal file
74
tests/baselines/reference/exportNestedNamespaces.symbols
Normal file
|
@ -0,0 +1,74 @@
|
|||
=== tests/cases/conformance/salsa/mod.js ===
|
||||
exports.n = {};
|
||||
>exports.n : Symbol(n, Decl(mod.js, 0, 0))
|
||||
>exports : Symbol(n, Decl(mod.js, 0, 0))
|
||||
>n : Symbol(n, Decl(mod.js, 0, 0))
|
||||
|
||||
exports.n.K = function () {
|
||||
>exports.n.K : Symbol(K, Decl(mod.js, 0, 15))
|
||||
>exports.n : Symbol(K, Decl(mod.js, 0, 15))
|
||||
>exports : Symbol("tests/cases/conformance/salsa/mod", Decl(mod.js, 0, 0))
|
||||
>n : Symbol(n, Decl(mod.js, 0, 0))
|
||||
>K : Symbol(K, Decl(mod.js, 0, 15))
|
||||
|
||||
this.x = 10;
|
||||
>this : Symbol(__object, Decl(mod.js, 0, 11), Decl(mod.js, 1, 8))
|
||||
>x : Symbol((Anonymous function).x, Decl(mod.js, 1, 27))
|
||||
}
|
||||
exports.Classic = class {
|
||||
>exports.Classic : Symbol(Classic, Decl(mod.js, 3, 1))
|
||||
>exports : Symbol(Classic, Decl(mod.js, 3, 1))
|
||||
>Classic : Symbol(Classic, Decl(mod.js, 3, 1))
|
||||
|
||||
constructor() {
|
||||
this.p = 1
|
||||
>this.p : Symbol((Anonymous class).p, Decl(mod.js, 5, 19))
|
||||
>this : Symbol((Anonymous class), Decl(mod.js, 4, 17))
|
||||
>p : Symbol((Anonymous class).p, Decl(mod.js, 5, 19))
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/salsa/use.js ===
|
||||
import * as s from './mod'
|
||||
>s : Symbol(s, Decl(use.js, 0, 6))
|
||||
|
||||
var k = new s.n.K()
|
||||
>k : Symbol(k, Decl(use.js, 2, 3))
|
||||
>s.n.K : Symbol(K, Decl(mod.js, 0, 15))
|
||||
>s.n : Symbol(s.n, Decl(mod.js, 0, 0))
|
||||
>s : Symbol(s, Decl(use.js, 0, 6))
|
||||
>n : Symbol(s.n, Decl(mod.js, 0, 0))
|
||||
>K : Symbol(K, Decl(mod.js, 0, 15))
|
||||
|
||||
k.x
|
||||
>k.x : Symbol((Anonymous function).x, Decl(mod.js, 1, 27))
|
||||
>k : Symbol(k, Decl(use.js, 2, 3))
|
||||
>x : Symbol((Anonymous function).x, Decl(mod.js, 1, 27))
|
||||
|
||||
var classic = new s.Classic()
|
||||
>classic : Symbol(classic, Decl(use.js, 4, 3))
|
||||
>s.Classic : Symbol(s.Classic, Decl(mod.js, 3, 1))
|
||||
>s : Symbol(s, Decl(use.js, 0, 6))
|
||||
>Classic : Symbol(s.Classic, Decl(mod.js, 3, 1))
|
||||
|
||||
|
||||
/** @param {s.n.K} c
|
||||
@param {s.Classic} classic */
|
||||
function f(c, classic) {
|
||||
>f : Symbol(f, Decl(use.js, 4, 29))
|
||||
>c : Symbol(c, Decl(use.js, 9, 11))
|
||||
>classic : Symbol(classic, Decl(use.js, 9, 13))
|
||||
|
||||
c.x
|
||||
>c.x : Symbol((Anonymous function).x, Decl(mod.js, 1, 27))
|
||||
>c : Symbol(c, Decl(use.js, 9, 11))
|
||||
>x : Symbol((Anonymous function).x, Decl(mod.js, 1, 27))
|
||||
|
||||
classic.p
|
||||
>classic.p : Symbol((Anonymous class).p, Decl(mod.js, 5, 19))
|
||||
>classic : Symbol(classic, Decl(use.js, 9, 13))
|
||||
>p : Symbol((Anonymous class).p, Decl(mod.js, 5, 19))
|
||||
}
|
||||
|
||||
|
||||
|
87
tests/baselines/reference/exportNestedNamespaces.types
Normal file
87
tests/baselines/reference/exportNestedNamespaces.types
Normal file
|
@ -0,0 +1,87 @@
|
|||
=== tests/cases/conformance/salsa/mod.js ===
|
||||
exports.n = {};
|
||||
>exports.n = {} : typeof __object
|
||||
>exports.n : typeof __object
|
||||
>exports : typeof "tests/cases/conformance/salsa/mod"
|
||||
>n : typeof __object
|
||||
>{} : typeof __object
|
||||
|
||||
exports.n.K = function () {
|
||||
>exports.n.K = function () { this.x = 10;} : () => void
|
||||
>exports.n.K : () => void
|
||||
>exports.n : typeof __object
|
||||
>exports : typeof "tests/cases/conformance/salsa/mod"
|
||||
>n : typeof __object
|
||||
>K : () => void
|
||||
>function () { this.x = 10;} : () => void
|
||||
|
||||
this.x = 10;
|
||||
>this.x = 10 : 10
|
||||
>this.x : any
|
||||
>this : typeof __object
|
||||
>x : any
|
||||
>10 : 10
|
||||
}
|
||||
exports.Classic = class {
|
||||
>exports.Classic = class { constructor() { this.p = 1 }} : typeof (Anonymous class)
|
||||
>exports.Classic : typeof (Anonymous class)
|
||||
>exports : typeof "tests/cases/conformance/salsa/mod"
|
||||
>Classic : typeof (Anonymous class)
|
||||
>class { constructor() { this.p = 1 }} : typeof (Anonymous class)
|
||||
|
||||
constructor() {
|
||||
this.p = 1
|
||||
>this.p = 1 : 1
|
||||
>this.p : number
|
||||
>this : this
|
||||
>p : number
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/salsa/use.js ===
|
||||
import * as s from './mod'
|
||||
>s : typeof s
|
||||
|
||||
var k = new s.n.K()
|
||||
>k : { x: number; }
|
||||
>new s.n.K() : { x: number; }
|
||||
>s.n.K : () => void
|
||||
>s.n : typeof __object
|
||||
>s : typeof s
|
||||
>n : typeof __object
|
||||
>K : () => void
|
||||
|
||||
k.x
|
||||
>k.x : number
|
||||
>k : { x: number; }
|
||||
>x : number
|
||||
|
||||
var classic = new s.Classic()
|
||||
>classic : (Anonymous class)
|
||||
>new s.Classic() : (Anonymous class)
|
||||
>s.Classic : typeof (Anonymous class)
|
||||
>s : typeof s
|
||||
>Classic : typeof (Anonymous class)
|
||||
|
||||
|
||||
/** @param {s.n.K} c
|
||||
@param {s.Classic} classic */
|
||||
function f(c, classic) {
|
||||
>f : (c: { x: number; }, classic: (Anonymous class)) => void
|
||||
>c : { x: number; }
|
||||
>classic : (Anonymous class)
|
||||
|
||||
c.x
|
||||
>c.x : number
|
||||
>c : { x: number; }
|
||||
>x : number
|
||||
|
||||
classic.p
|
||||
>classic.p : number
|
||||
>classic : (Anonymous class)
|
||||
>p : number
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
tests/cases/conformance/salsa/mod.js(1,1): error TS2304: Cannot find name 'module'.
|
||||
tests/cases/conformance/salsa/mod.js(2,1): error TS2304: Cannot find name 'module'.
|
||||
tests/cases/conformance/salsa/mod.js(5,1): error TS2304: Cannot find name 'module'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/salsa/mod.js (3 errors) ====
|
||||
module.exports.n = {};
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'module'.
|
||||
module.exports.n.K = function C() {
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'module'.
|
||||
this.x = 10;
|
||||
}
|
||||
module.exports.Classic = class {
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'module'.
|
||||
constructor() {
|
||||
this.p = 1
|
||||
}
|
||||
}
|
||||
|
||||
==== tests/cases/conformance/salsa/use.js (0 errors) ====
|
||||
import * as s from './mod'
|
||||
|
||||
var k = new s.n.K()
|
||||
k.x
|
||||
var classic = new s.Classic()
|
||||
|
||||
|
||||
/** @param {s.n.K} c
|
||||
@param {s.Classic} classic */
|
||||
function f(c, classic) {
|
||||
c.x
|
||||
classic.p
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
=== tests/cases/conformance/salsa/mod.js ===
|
||||
module.exports.n = {};
|
||||
>module.exports : Symbol(n, Decl(mod.js, 0, 0))
|
||||
>n : Symbol(n, Decl(mod.js, 0, 0))
|
||||
|
||||
module.exports.n.K = function C() {
|
||||
>module.exports.n : Symbol(K, Decl(mod.js, 0, 22))
|
||||
>K : Symbol(K, Decl(mod.js, 0, 22))
|
||||
>C : Symbol(C, Decl(mod.js, 1, 20))
|
||||
|
||||
this.x = 10;
|
||||
>x : Symbol(C.x, Decl(mod.js, 1, 35))
|
||||
}
|
||||
module.exports.Classic = class {
|
||||
>module.exports : Symbol(Classic, Decl(mod.js, 3, 1))
|
||||
>Classic : Symbol(Classic, Decl(mod.js, 3, 1))
|
||||
|
||||
constructor() {
|
||||
this.p = 1
|
||||
>this.p : Symbol((Anonymous class).p, Decl(mod.js, 5, 19))
|
||||
>this : Symbol((Anonymous class), Decl(mod.js, 4, 24))
|
||||
>p : Symbol((Anonymous class).p, Decl(mod.js, 5, 19))
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/salsa/use.js ===
|
||||
import * as s from './mod'
|
||||
>s : Symbol(s, Decl(use.js, 0, 6))
|
||||
|
||||
var k = new s.n.K()
|
||||
>k : Symbol(k, Decl(use.js, 2, 3))
|
||||
>s.n.K : Symbol(K, Decl(mod.js, 0, 22))
|
||||
>s.n : Symbol(s.n, Decl(mod.js, 0, 0))
|
||||
>s : Symbol(s, Decl(use.js, 0, 6))
|
||||
>n : Symbol(s.n, Decl(mod.js, 0, 0))
|
||||
>K : Symbol(K, Decl(mod.js, 0, 22))
|
||||
|
||||
k.x
|
||||
>k.x : Symbol(C.x, Decl(mod.js, 1, 35))
|
||||
>k : Symbol(k, Decl(use.js, 2, 3))
|
||||
>x : Symbol(C.x, Decl(mod.js, 1, 35))
|
||||
|
||||
var classic = new s.Classic()
|
||||
>classic : Symbol(classic, Decl(use.js, 4, 3))
|
||||
>s.Classic : Symbol(s.Classic, Decl(mod.js, 3, 1))
|
||||
>s : Symbol(s, Decl(use.js, 0, 6))
|
||||
>Classic : Symbol(s.Classic, Decl(mod.js, 3, 1))
|
||||
|
||||
|
||||
/** @param {s.n.K} c
|
||||
@param {s.Classic} classic */
|
||||
function f(c, classic) {
|
||||
>f : Symbol(f, Decl(use.js, 4, 29))
|
||||
>c : Symbol(c, Decl(use.js, 9, 11))
|
||||
>classic : Symbol(classic, Decl(use.js, 9, 13))
|
||||
|
||||
c.x
|
||||
>c.x : Symbol(C.x, Decl(mod.js, 1, 35))
|
||||
>c : Symbol(c, Decl(use.js, 9, 11))
|
||||
>x : Symbol(C.x, Decl(mod.js, 1, 35))
|
||||
|
||||
classic.p
|
||||
>classic.p : Symbol((Anonymous class).p, Decl(mod.js, 5, 19))
|
||||
>classic : Symbol(classic, Decl(use.js, 9, 13))
|
||||
>p : Symbol((Anonymous class).p, Decl(mod.js, 5, 19))
|
||||
}
|
||||
|
92
tests/baselines/reference/moduleExportNestedNamespaces.types
Normal file
92
tests/baselines/reference/moduleExportNestedNamespaces.types
Normal file
|
@ -0,0 +1,92 @@
|
|||
=== tests/cases/conformance/salsa/mod.js ===
|
||||
module.exports.n = {};
|
||||
>module.exports.n = {} : typeof __object
|
||||
>module.exports.n : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>n : any
|
||||
>{} : typeof __object
|
||||
|
||||
module.exports.n.K = function C() {
|
||||
>module.exports.n.K = function C() { this.x = 10;} : () => void
|
||||
>module.exports.n.K : any
|
||||
>module.exports.n : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>n : any
|
||||
>K : any
|
||||
>function C() { this.x = 10;} : () => void
|
||||
>C : () => void
|
||||
|
||||
this.x = 10;
|
||||
>this.x = 10 : 10
|
||||
>this.x : any
|
||||
>this : any
|
||||
>x : any
|
||||
>10 : 10
|
||||
}
|
||||
module.exports.Classic = class {
|
||||
>module.exports.Classic = class { constructor() { this.p = 1 }} : typeof (Anonymous class)
|
||||
>module.exports.Classic : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>Classic : any
|
||||
>class { constructor() { this.p = 1 }} : typeof (Anonymous class)
|
||||
|
||||
constructor() {
|
||||
this.p = 1
|
||||
>this.p = 1 : 1
|
||||
>this.p : number
|
||||
>this : this
|
||||
>p : number
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/salsa/use.js ===
|
||||
import * as s from './mod'
|
||||
>s : typeof s
|
||||
|
||||
var k = new s.n.K()
|
||||
>k : { x: number; }
|
||||
>new s.n.K() : { x: number; }
|
||||
>s.n.K : () => void
|
||||
>s.n : typeof __object
|
||||
>s : typeof s
|
||||
>n : typeof __object
|
||||
>K : () => void
|
||||
|
||||
k.x
|
||||
>k.x : number
|
||||
>k : { x: number; }
|
||||
>x : number
|
||||
|
||||
var classic = new s.Classic()
|
||||
>classic : (Anonymous class)
|
||||
>new s.Classic() : (Anonymous class)
|
||||
>s.Classic : typeof (Anonymous class)
|
||||
>s : typeof s
|
||||
>Classic : typeof (Anonymous class)
|
||||
|
||||
|
||||
/** @param {s.n.K} c
|
||||
@param {s.Classic} classic */
|
||||
function f(c, classic) {
|
||||
>f : (c: { x: number; }, classic: (Anonymous class)) => void
|
||||
>c : { x: number; }
|
||||
>classic : (Anonymous class)
|
||||
|
||||
c.x
|
||||
>c.x : number
|
||||
>c : { x: number; }
|
||||
>x : number
|
||||
|
||||
classic.p
|
||||
>classic.p : number
|
||||
>classic : (Anonymous class)
|
||||
>p : number
|
||||
}
|
||||
|
31
tests/cases/conformance/salsa/exportNestedNamespaces.ts
Normal file
31
tests/cases/conformance/salsa/exportNestedNamespaces.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @Filename: mod.js
|
||||
|
||||
exports.n = {};
|
||||
exports.n.K = function () {
|
||||
this.x = 10;
|
||||
}
|
||||
exports.Classic = class {
|
||||
constructor() {
|
||||
this.p = 1
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: use.js
|
||||
import * as s from './mod'
|
||||
|
||||
var k = new s.n.K()
|
||||
k.x
|
||||
var classic = new s.Classic()
|
||||
|
||||
|
||||
/** @param {s.n.K} c
|
||||
@param {s.Classic} classic */
|
||||
function f(c, classic) {
|
||||
c.x
|
||||
classic.p
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @Filename: mod.js
|
||||
|
||||
module.exports.n = {};
|
||||
module.exports.n.K = function C() {
|
||||
this.x = 10;
|
||||
}
|
||||
module.exports.Classic = class {
|
||||
constructor() {
|
||||
this.p = 1
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: use.js
|
||||
import * as s from './mod'
|
||||
|
||||
var k = new s.n.K()
|
||||
k.x
|
||||
var classic = new s.Classic()
|
||||
|
||||
|
||||
/** @param {s.n.K} c
|
||||
@param {s.Classic} classic */
|
||||
function f(c, classic) {
|
||||
c.x
|
||||
classic.p
|
||||
}
|
Loading…
Reference in a new issue