diff --git a/CHANGES.md b/CHANGES.md
index b5e737e7f07..3bc87f5b92f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -70,7 +70,6 @@ However, if you see **_incorrect_** `.d.ts` output from a `.js` file, **please f
| Identifier-named typedefs |
`/** @typedef {T} */ typeName;
| /** @typedef {T} typeName */
| Closure feature. |
| Closure function type syntax | /* @type {function(string): void} */
| /* @type {(s: string) => void} */
| |
| Automatic typeof insertion | const o = { a: 1 };
/\** @type {o} */
var o2 = { a: 1 };
| const o = { a: 1 };
/\** @type {typeof o} */
var o2 = { a: 1 };
| |
-| `@typedef` nested names | /** @typedef {1} NS.T */
| Translate to .d.ts file. | Also applies to `@callback`. |
## Expando declarations
diff --git a/_packages/native-preview/src/api/node/node.generated.ts b/_packages/native-preview/src/api/node/node.generated.ts
index bceb6d788fd..9f4fe8ef548 100644
--- a/_packages/native-preview/src/api/node/node.generated.ts
+++ b/_packages/native-preview/src/api/node/node.generated.ts
@@ -653,9 +653,6 @@ export class RemoteNode extends RemoteNodeBase implements Node {
get finallyBlock(): RemoteNode | undefined {
return this.getNamedChild("finallyBlock") as RemoteNode;
}
- get fullName(): RemoteNode | undefined {
- return this.getNamedChild("fullName") as RemoteNode;
- }
get head(): RemoteNode | undefined {
return this.getNamedChild("head") as RemoteNode;
}
diff --git a/_packages/native-preview/src/api/node/protocol.generated.ts b/_packages/native-preview/src/api/node/protocol.generated.ts
index 504babfece7..4253d34aad5 100644
--- a/_packages/native-preview/src/api/node/protocol.generated.ts
+++ b/_packages/native-preview/src/api/node/protocol.generated.ts
@@ -156,7 +156,7 @@ export const childProperties: Readonly = {
[SyntaxKind.JSDocCallbackTag]: (data, cbNode, cbNodes) =>
visitNode(cbNode, data.tagName) ||
visitNode(cbNode, data.typeExpression) ||
- visitNode(cbNode, data.fullName) ||
+ visitNode(cbNode, data.name) ||
visitNodes(cbNode, cbNodes, data.comment),
[SyntaxKind.JSDocOverloadTag]: (data, cbNode, cbNodes) =>
visitNode(cbNode, data.tagName) ||
@@ -2860,11 +2858,11 @@ export function createJSDocImportTag(tagName: Identifier, importClause: ImportCl
}) as unknown as JSDocImportTag;
}
-export function createJSDocCallbackTag(tagName: Identifier, typeExpression: TypeNode, fullName?: Node, comment?: readonly JSDocComment[]): JSDocCallbackTag {
+export function createJSDocCallbackTag(tagName: Identifier, typeExpression: TypeNode, name?: JSDocFullName, comment?: readonly JSDocComment[]): JSDocCallbackTag {
return new NodeObject(SyntaxKind.JSDocCallbackTag, {
tagName,
typeExpression,
- fullName,
+ name,
comment: comment ? createNodeArray(comment) : undefined,
}) as unknown as JSDocCallbackTag;
}
@@ -2877,7 +2875,7 @@ export function createJSDocOverloadTag(tagName: Identifier, typeExpression: Type
}) as unknown as JSDocOverloadTag;
}
-export function createJSDocTypedefTag(tagName: Identifier, typeExpression?: Node, name?: Identifier, comment?: readonly JSDocComment[]): JSDocTypedefTag {
+export function createJSDocTypedefTag(tagName: Identifier, typeExpression?: Node, name?: JSDocFullName, comment?: readonly JSDocComment[]): JSDocTypedefTag {
return new NodeObject(SyntaxKind.JSDocTypedefTag, {
tagName,
typeExpression,
@@ -3651,15 +3649,15 @@ export function updateJSDocImportTag(node: JSDocImportTag, tagName: Identifier,
return node.tagName !== tagName || node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier || node.attributes !== attributes || node.comment !== comment ? createJSDocImportTag(tagName, importClause, moduleSpecifier, attributes, comment) : node;
}
-export function updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier, typeExpression: TypeNode, fullName?: Node, comment?: readonly JSDocComment[]): JSDocCallbackTag {
- return node.tagName !== tagName || node.typeExpression !== typeExpression || node.fullName !== fullName || node.comment !== comment ? createJSDocCallbackTag(tagName, typeExpression, fullName, comment) : node;
+export function updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier, typeExpression: TypeNode, name?: JSDocFullName, comment?: readonly JSDocComment[]): JSDocCallbackTag {
+ return node.tagName !== tagName || node.typeExpression !== typeExpression || node.name !== name || node.comment !== comment ? createJSDocCallbackTag(tagName, typeExpression, name, comment) : node;
}
export function updateJSDocOverloadTag(node: JSDocOverloadTag, tagName: Identifier, typeExpression: TypeNode, comment?: readonly JSDocComment[]): JSDocOverloadTag {
return node.tagName !== tagName || node.typeExpression !== typeExpression || node.comment !== comment ? createJSDocOverloadTag(tagName, typeExpression, comment) : node;
}
-export function updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier, typeExpression?: Node, name?: Identifier, comment?: readonly JSDocComment[]): JSDocTypedefTag {
+export function updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier, typeExpression?: Node, name?: JSDocFullName, comment?: readonly JSDocComment[]): JSDocTypedefTag {
return node.tagName !== tagName || node.typeExpression !== typeExpression || node.name !== name || node.comment !== comment ? createJSDocTypedefTag(tagName, typeExpression, name, comment) : node;
}
diff --git a/_packages/native-preview/src/ast/is.generated.ts b/_packages/native-preview/src/ast/is.generated.ts
index d29ab4d5a06..af226c91b6e 100644
--- a/_packages/native-preview/src/ast/is.generated.ts
+++ b/_packages/native-preview/src/ast/is.generated.ts
@@ -126,6 +126,7 @@ import type {
JSDocCallbackTag,
JSDocComment,
JSDocDeprecatedTag,
+ JSDocFullName,
JSDocImplementsTag,
JSDocImportTag,
JSDocLink,
@@ -1143,6 +1144,10 @@ export function isModuleBody(node: Node): node is ModuleBody {
return node.kind === SyntaxKind.ModuleBlock || node.kind === SyntaxKind.ModuleDeclaration;
}
+export function isJSDocFullName(node: Node): node is JSDocFullName {
+ return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ModuleDeclaration;
+}
+
export function isModuleReference(node: Node): node is ModuleReference {
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.ExternalModuleReference;
}
diff --git a/_packages/native-preview/src/ast/visitor.generated.ts b/_packages/native-preview/src/ast/visitor.generated.ts
index 792dd10cf12..03829048b5e 100644
--- a/_packages/native-preview/src/ast/visitor.generated.ts
+++ b/_packages/native-preview/src/ast/visitor.generated.ts
@@ -373,6 +373,7 @@ import {
isImportAttributeName,
isImportAttributes,
isImportClause,
+ isJSDocFullName,
isJsxAttributeName,
isJsxAttributes,
isJsxAttributeValue,
@@ -1306,9 +1307,9 @@ const visitEachChildTable: Record = {
[SyntaxKind.JSDocCallbackTag]: (node: JSDocCallbackTag, visitor: Visitor): JSDocCallbackTag => {
const _tagName = visitNode(node.tagName, visitor, isIdentifier);
const _typeExpression = visitNode(node.typeExpression, visitor, isTypeNode);
- const _fullName = visitNode(node.fullName, visitor);
+ const _name = visitNode(node.name, visitor, isJSDocFullName);
const _comment = visitNodes(node.comment, visitor);
- return updateJSDocCallbackTag(node, _tagName, _typeExpression, _fullName, _comment);
+ return updateJSDocCallbackTag(node, _tagName, _typeExpression, _name, _comment);
},
[SyntaxKind.JSDocOverloadTag]: (node: JSDocOverloadTag, visitor: Visitor): JSDocOverloadTag => {
const _tagName = visitNode(node.tagName, visitor, isIdentifier);
@@ -1319,7 +1320,7 @@ const visitEachChildTable: Record = {
[SyntaxKind.JSDocTypedefTag]: (node: JSDocTypedefTag, visitor: Visitor): JSDocTypedefTag => {
const _tagName = visitNode(node.tagName, visitor, isIdentifier);
const _typeExpression = visitNode(node.typeExpression, visitor);
- const _name = visitNode(node.name, visitor, isIdentifier);
+ const _name = visitNode(node.name, visitor, isJSDocFullName);
const _comment = visitNodes(node.comment, visitor);
return updateJSDocTypedefTag(node, _tagName, _typeExpression, _name, _comment);
},
diff --git a/_packages/native-preview/src/enums/nodeFlags.enum.ts b/_packages/native-preview/src/enums/nodeFlags.enum.ts
index 16df62b0345..605260208a6 100644
--- a/_packages/native-preview/src/enums/nodeFlags.enum.ts
+++ b/_packages/native-preview/src/enums/nodeFlags.enum.ts
@@ -39,4 +39,6 @@ export enum NodeFlags {
TypeExcludesFlags = YieldContext | AwaitContext,
PermanentlySetIncrementalFlags = PossiblyContainsDynamicImport | PossiblyContainsImportMeta,
IdentifierHasExtendedUnicodeEscape = ContainsThis,
+ IdentifierIsInJSDocNamespace = HasAsyncFunctions,
+ NestedNamespace = OptionalChain,
}
diff --git a/_packages/native-preview/src/enums/nodeFlags.ts b/_packages/native-preview/src/enums/nodeFlags.ts
index 154525c5f41..0324184fefc 100644
--- a/_packages/native-preview/src/enums/nodeFlags.ts
+++ b/_packages/native-preview/src/enums/nodeFlags.ts
@@ -39,4 +39,6 @@ export var NodeFlags: any;
NodeFlags[NodeFlags["TypeExcludesFlags"] = 10240] = "TypeExcludesFlags";
NodeFlags[NodeFlags["PermanentlySetIncrementalFlags"] = 1572864] = "PermanentlySetIncrementalFlags";
NodeFlags[NodeFlags["IdentifierHasExtendedUnicodeEscape"] = 128] = "IdentifierHasExtendedUnicodeEscape";
+ NodeFlags[NodeFlags["IdentifierIsInJSDocNamespace"] = 262144] = "IdentifierIsInJSDocNamespace";
+ NodeFlags[NodeFlags["NestedNamespace"] = 32] = "NestedNamespace";
})(NodeFlags || (NodeFlags = {}));
diff --git a/_scripts/ast.json b/_scripts/ast.json
index 77bd4daa008..62ff0d868b5 100644
--- a/_scripts/ast.json
+++ b/_scripts/ast.json
@@ -4664,8 +4664,9 @@
"type": "TypeNode"
},
{
- "name": "FullName",
- "type": "Node",
+ "name": "name",
+ "type": "JSDocFullName",
+ "private": true,
"optional": true
},
{
@@ -4709,7 +4710,7 @@
},
{
"name": "name",
- "type": "Identifier",
+ "type": "JSDocFullName",
"private": true,
"optional": true
},
@@ -5177,6 +5178,10 @@
"ModuleBlock",
"ModuleDeclaration"
],
+ "JSDocFullName": [
+ "Identifier",
+ "ModuleDeclaration"
+ ],
"ForInitializer": [
"Expression",
"MissingDeclaration",
diff --git a/internal/api/encoder/decoder_generated.go b/internal/api/encoder/decoder_generated.go
index 362146b70be..29dff5c5310 100644
--- a/internal/api/encoder/decoder_generated.go
+++ b/internal/api/encoder/decoder_generated.go
@@ -1030,9 +1030,9 @@ func (d *astDecoder) createChildrenNode(kind ast.Kind, data uint32, childIndices
it := newChildIter(childIndices)
tagName := d.nodeAt(it.nextIf(mask, 0))
typeExpression := d.nodeAt(it.nextIf(mask, 1))
- fullName := d.nodeAt(it.nextIf(mask, 2))
+ name := d.nodeAt(it.nextIf(mask, 2))
comment := d.nodeListAt(it.nextIf(mask, 3))
- return d.factory.NewJSDocCallbackTag(tagName, typeExpression, fullName, comment), nil
+ return d.factory.NewJSDocCallbackTag(tagName, typeExpression, name, comment), nil
case ast.KindJSDocOverloadTag:
it := newChildIter(childIndices)
tagName := d.nodeAt(it.nextIf(mask, 0))
diff --git a/internal/api/encoder/encoder_generated.go b/internal/api/encoder/encoder_generated.go
index abd8e9ec5e5..c77e287e63b 100644
--- a/internal/api/encoder/encoder_generated.go
+++ b/internal/api/encoder/encoder_generated.go
@@ -481,7 +481,7 @@ func getChildrenPropertyMask(node *ast.Node) uint8 {
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.ImportClause != nil) << 1) | (boolToByte(n.ModuleSpecifier != nil) << 2) | (boolToByte(n.Attributes != nil) << 3) | (boolToByte(n.Comment != nil) << 4)
case ast.KindJSDocCallbackTag:
n := node.AsJSDocCallbackTag()
- return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.FullName != nil) << 2) | (boolToByte(n.Comment != nil) << 3)
+ return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Name() != nil) << 2) | (boolToByte(n.Comment != nil) << 3)
case ast.KindJSDocOverloadTag:
n := node.AsJSDocOverloadTag()
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Comment != nil) << 2)
diff --git a/internal/ast/ast.go b/internal/ast/ast.go
index 92fb4cd8110..ba1f7641faf 100644
--- a/internal/ast/ast.go
+++ b/internal/ast/ast.go
@@ -1119,6 +1119,8 @@ func (n *Node) TypeExpression() *Node {
return n.AsJSDocTypeTag().TypeExpression
case KindJSDocTypedefTag:
return n.AsJSDocTypedefTag().TypeExpression
+ case KindJSDocCallbackTag:
+ return n.AsJSDocCallbackTag().TypeExpression
case KindJSDocSatisfiesTag:
return n.AsJSDocSatisfiesTag().TypeExpression
case KindJSDocThrowsTag:
diff --git a/internal/ast/ast_generated.go b/internal/ast/ast_generated.go
index 170cb457af0..7567b2e7833 100644
--- a/internal/ast/ast_generated.go
+++ b/internal/ast/ast_generated.go
@@ -525,6 +525,7 @@ type (
ModuleExportName = Node // Identifier | StringLiteral
PropertyName = Node // Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | BigIntLiteral
ModuleBody = Node // ModuleBlock | ModuleDeclaration
+ JSDocFullName = Node // Identifier | ModuleDeclaration
ForInitializer = Node // Expression | MissingDeclaration | VariableDeclarationList
ModuleReference = Node // Identifier | QualifiedName | ExternalModuleReference
NamedImportBindings = Node // NamespaceImport | NamedImports
@@ -7980,21 +7981,21 @@ func IsJSDocImportTag(node *Node) bool {
type JSDocCallbackTag struct {
JSDocTagBase
TypeExpression *TypeNode
- FullName *Node // Optional
+ name *JSDocFullName // Optional
}
-func (f *NodeFactory) NewJSDocCallbackTag(tagName *IdentifierNode, typeExpression *TypeNode, fullName *Node, comment *NodeList) *Node {
+func (f *NodeFactory) NewJSDocCallbackTag(tagName *IdentifierNode, typeExpression *TypeNode, name *JSDocFullName, comment *NodeList) *Node {
data := &JSDocCallbackTag{}
data.TagName = tagName
data.TypeExpression = typeExpression
- data.FullName = fullName
+ data.name = name
data.Comment = comment
return f.newNode(KindJSDocCallbackTag, data)
}
-func (f *NodeFactory) UpdateJSDocCallbackTag(node *JSDocCallbackTag, tagName *IdentifierNode, typeExpression *TypeNode, fullName *Node, comment *NodeList) *Node {
- if tagName != node.TagName || typeExpression != node.TypeExpression || fullName != node.FullName || comment != node.Comment {
- return updateNode(f.NewJSDocCallbackTag(tagName, typeExpression, fullName, comment), node.AsNode(), f.hooks)
+func (f *NodeFactory) UpdateJSDocCallbackTag(node *JSDocCallbackTag, tagName *IdentifierNode, typeExpression *TypeNode, name *JSDocFullName, comment *NodeList) *Node {
+ if tagName != node.TagName || typeExpression != node.TypeExpression || name != node.name || comment != node.Comment {
+ return updateNode(f.NewJSDocCallbackTag(tagName, typeExpression, name, comment), node.AsNode(), f.hooks)
}
return node.AsNode()
}
@@ -8002,16 +8003,20 @@ func (f *NodeFactory) UpdateJSDocCallbackTag(node *JSDocCallbackTag, tagName *Id
func (node *JSDocCallbackTag) ForEachChild(v Visitor) bool {
return visit(v, node.TagName) ||
visit(v, node.TypeExpression) ||
- visit(v, node.FullName) ||
+ visit(v, node.name) ||
visitNodeList(v, node.Comment)
}
func (node *JSDocCallbackTag) VisitEachChild(v *NodeVisitor) *Node {
- return v.Factory.UpdateJSDocCallbackTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNode(node.FullName), v.visitNodes(node.Comment))
+ return v.Factory.UpdateJSDocCallbackTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNode(node.name), v.visitNodes(node.Comment))
}
func (node *JSDocCallbackTag) Clone(f NodeFactoryCoercible) *Node {
- return cloneNode(f.AsNodeFactory().NewJSDocCallbackTag(node.TagName, node.TypeExpression, node.FullName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
+ return cloneNode(f.AsNodeFactory().NewJSDocCallbackTag(node.TagName, node.TypeExpression, node.name, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
+}
+
+func (node *JSDocCallbackTag) Name() *DeclarationName {
+ return node.name
}
func IsJSDocCallbackTag(node *Node) bool {
@@ -8064,11 +8069,11 @@ func IsJSDocOverloadTag(node *Node) bool {
type JSDocTypedefTag struct {
JSDocTagBase
- TypeExpression *Node // Optional
- name *IdentifierNode // Optional
+ TypeExpression *Node // Optional
+ name *JSDocFullName // Optional
}
-func (f *NodeFactory) NewJSDocTypedefTag(tagName *IdentifierNode, typeExpression *Node, name *IdentifierNode, comment *NodeList) *Node {
+func (f *NodeFactory) NewJSDocTypedefTag(tagName *IdentifierNode, typeExpression *Node, name *JSDocFullName, comment *NodeList) *Node {
data := &JSDocTypedefTag{}
data.TagName = tagName
data.TypeExpression = typeExpression
@@ -8077,7 +8082,7 @@ func (f *NodeFactory) NewJSDocTypedefTag(tagName *IdentifierNode, typeExpression
return f.newNode(KindJSDocTypedefTag, data)
}
-func (f *NodeFactory) UpdateJSDocTypedefTag(node *JSDocTypedefTag, tagName *IdentifierNode, typeExpression *Node, name *IdentifierNode, comment *NodeList) *Node {
+func (f *NodeFactory) UpdateJSDocTypedefTag(node *JSDocTypedefTag, tagName *IdentifierNode, typeExpression *Node, name *JSDocFullName, comment *NodeList) *Node {
if tagName != node.TagName || typeExpression != node.TypeExpression || name != node.name || comment != node.Comment {
return updateNode(f.NewJSDocTypedefTag(tagName, typeExpression, name, comment), node.AsNode(), f.hooks)
}
diff --git a/internal/ast/nodeflags.go b/internal/ast/nodeflags.go
index 6d3963d9fb8..bba2f98d5ca 100644
--- a/internal/ast/nodeflags.go
+++ b/internal/ast/nodeflags.go
@@ -64,5 +64,9 @@ const (
NodeFlagsPermanentlySetIncrementalFlags NodeFlags = NodeFlagsPossiblyContainsDynamicImport | NodeFlagsPossiblyContainsImportMeta
// The following flags repurpose other NodeFlags as different meanings for Identifier nodes
- NodeFlagsIdentifierHasExtendedUnicodeEscape NodeFlags = NodeFlagsContainsThis // Indicates whether the identifier contains an extended unicode escape sequence
+ NodeFlagsIdentifierHasExtendedUnicodeEscape NodeFlags = NodeFlagsContainsThis // Indicates whether the identifier contains an extended unicode escape sequence
+ NodeFlagsIdentifierIsInJSDocNamespace NodeFlags = NodeFlagsHasAsyncFunctions // Indicates the identifier is the innermost name of a JSDoc namespace declaration
+
+ // The following flag repurposes other NodeFlags for ModuleDeclaration nodes
+ NodeFlagsNestedNamespace NodeFlags = NodeFlagsOptionalChain // If ModuleDeclaration is a nested namespace (e.g. inner part of A.B.C)
)
diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go
index 1ed8e9284cd..8554c14276a 100644
--- a/internal/ast/utilities.go
+++ b/internal/ast/utilities.go
@@ -3713,7 +3713,7 @@ func IndexOfNode(nodes []*Node, node *Node) int {
}
func CompareNodePositions(n1, n2 *Node) int {
- return n1.Pos() - n2.Pos()
+ return core.CompareTextRanges(n1.Loc, n2.Loc)
}
func IsUnterminatedLiteral(node *Node) bool {
@@ -4146,8 +4146,16 @@ func TryGetImportFromModuleSpecifier(node *StringLiteralLike) *Node {
return nil
}
-func IsImplicitlyExportedJSTypeAlias(node *Node) bool {
- return IsJSTypeAliasDeclaration(node) && IsSourceFile(node.Parent) && IsExternalOrCommonJSModule(node.Parent.AsSourceFile())
+func IsImplicitlyExportedJSDocDeclaration(node *Node) bool {
+ if !IsSourceFile(node.Parent) || !IsExternalOrCommonJSModule(node.Parent.AsSourceFile()) {
+ return false
+ }
+ if IsJSTypeAliasDeclaration(node) {
+ return true
+ }
+ // A reparsed ModuleDeclaration synthesized from a JSDoc @typedef/@callback
+ // dotted name should also be treated as implicitly exported in modules.
+ return IsModuleDeclaration(node) && node.Flags&NodeFlagsReparsed != 0
}
func HasContextSensitiveParameters(node *Node) bool {
diff --git a/internal/binder/binder.go b/internal/binder/binder.go
index 29ecc50001d..28de0e95104 100644
--- a/internal/binder/binder.go
+++ b/internal/binder/binder.go
@@ -379,7 +379,7 @@ func GetSymbolNameForPrivateIdentifier(containingClassSymbol *ast.Symbol, descri
func (b *Binder) declareModuleMember(node *ast.Node, symbolFlags ast.SymbolFlags, symbolExcludes ast.SymbolFlags) *ast.Symbol {
container := b.container
- hasExportModifier := ast.GetCombinedModifierFlags(node)&ast.ModifierFlagsExport != 0 || ast.IsImplicitlyExportedJSTypeAlias(node)
+ hasExportModifier := ast.GetCombinedModifierFlags(node)&ast.ModifierFlagsExport != 0 || ast.IsImplicitlyExportedJSDocDeclaration(node)
if symbolFlags&ast.SymbolFlagsAlias != 0 {
if node.Kind == ast.KindExportSpecifier || (node.Kind == ast.KindImportEqualsDeclaration && hasExportModifier) {
return b.declareSymbol(ast.GetExports(container.Symbol()), container.Symbol(), node, symbolFlags, symbolExcludes)
@@ -426,7 +426,7 @@ func (b *Binder) declareClassMember(node *ast.Node, symbolFlags ast.SymbolFlags,
}
func (b *Binder) declareSourceFileMember(node *ast.Node, symbolFlags ast.SymbolFlags, symbolExcludes ast.SymbolFlags) *ast.Symbol {
- if ast.IsExternalOrCommonJSModule(b.file) {
+ if ast.IsExternalModule(b.file) {
return b.declareModuleMember(node, symbolFlags, symbolExcludes)
}
return b.declareSymbol(ast.GetLocals(b.file.AsNode()), nil /*parent*/, node, symbolFlags, symbolExcludes)
diff --git a/internal/checker/emitresolver.go b/internal/checker/emitresolver.go
index 5a108bd3c14..ac1f9d945e7 100644
--- a/internal/checker/emitresolver.go
+++ b/internal/checker/emitresolver.go
@@ -157,7 +157,7 @@ func (r *EmitResolver) determineIfDeclarationIsVisible(node *ast.Node) bool {
}
// External module augmentation is always visible
// A @typedef at top-level in an external module is always visible
- if ast.IsExternalModuleAugmentation(node) || ast.IsImplicitlyExportedJSTypeAlias(node) {
+ if ast.IsExternalModuleAugmentation(node) || ast.IsImplicitlyExportedJSDocDeclaration(node) {
return true
}
parent := ast.GetDeclarationContainer(node)
@@ -219,6 +219,15 @@ func (r *EmitResolver) determineIfDeclarationIsVisible(node *ast.Node) bool {
case ast.KindExportAssignment:
return false
+ // An `export {X}` (without a module specifier) is itself a visible re-export of
+ // the named binding; it contributes to the symbol's external visibility.
+ case ast.KindExportSpecifier:
+ exportDecl := node.Parent.Parent
+ if ast.IsExportDeclaration(exportDecl) && exportDecl.AsExportDeclaration().ModuleSpecifier == nil {
+ return r.isDeclarationVisible(exportDecl.Parent)
+ }
+ return false
+
default:
return false
}
@@ -391,7 +400,6 @@ func (r *EmitResolver) hasVisibleDeclarations(symbol *ast.Symbol, shouldComputeA
if ast.IsIdentifier(declaration) {
continue
}
-
if !r.isDeclarationVisible(declaration) {
// Mark the unexported alias as visible if its parent is visible
// because these kind of aliases can be used to name types in declaration file
diff --git a/internal/checker/symbolaccessibility.go b/internal/checker/symbolaccessibility.go
index 600a6988bb4..5505ae840d7 100644
--- a/internal/checker/symbolaccessibility.go
+++ b/internal/checker/symbolaccessibility.go
@@ -759,7 +759,7 @@ func (c *Checker) someSymbolTableInScope(
if ast.IsSourceFile(location) && !ast.IsExternalOrCommonJSModule(location.AsSourceFile()) {
break
}
- sym := c.getSymbolOfDeclaration(location)
+ sym := c.getSymbolOfDeclaration(ast.GetReparsedNodeForNode(location))
if callback(sym.Exports, symbolTableIDFromExports(sym), false, true, location) {
return true
}
diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt
index b9bb35865a1..6b5b6c602c4 100644
--- a/internal/fourslash/_scripts/failingTests.txt
+++ b/internal/fourslash/_scripts/failingTests.txt
@@ -311,7 +311,6 @@ TestJsDocServices
TestJsDocTagsWithHyphen
TestJsdocTemplatePrototypeCompletions
TestJsdocTypedefTag
-TestJsdocTypedefTag2
TestJsdocTypedefTagNamespace
TestJsFileImportNoTypes2
TestJsQuickInfoGenerallyAcceptableSize
diff --git a/internal/ls/importTracker.go b/internal/ls/importTracker.go
index 6c971b55ec9..983a8a2aa66 100644
--- a/internal/ls/importTracker.go
+++ b/internal/ls/importTracker.go
@@ -531,7 +531,7 @@ func getImportOrExportSymbol(node *ast.Node, symbol *ast.Symbol, checker *checke
} else {
exportNode := getExportNode(parent, node)
switch {
- case exportNode != nil && (ast.HasSyntacticModifier(exportNode, ast.ModifierFlagsExport) || ast.IsImplicitlyExportedJSTypeAlias(exportNode)):
+ case exportNode != nil && (ast.HasSyntacticModifier(exportNode, ast.ModifierFlagsExport) || ast.IsImplicitlyExportedJSDocDeclaration(exportNode)):
if ast.IsImportEqualsDeclaration(exportNode) && exportNode.AsImportEqualsDeclaration().ModuleReference == node {
// We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement.
if comingFromExport {
diff --git a/internal/parser/jsdoc.go b/internal/parser/jsdoc.go
index 51654d2576f..b2b37dec371 100644
--- a/internal/parser/jsdoc.go
+++ b/internal/parser/jsdoc.go
@@ -987,10 +987,38 @@ func (p *Parser) parseThisTag(start int, tagName *ast.IdentifierNode, margin int
return p.finishNode(result, start)
}
+func (p *Parser) parseJSDocTypeNameWithNamespace(nested bool) *ast.Node {
+ start := p.scanner.TokenStart()
+ if !tokenIsIdentifierOrKeyword(p.token) {
+ return nil
+ }
+ typeNameOrNamespaceName := p.parseJSDocIdentifierName(nil)
+ if p.parseOptionalJsdoc(ast.KindDotToken) {
+ body := p.parseJSDocTypeNameWithNamespace(true /*nested*/)
+ jsDocNamespaceNode := p.factory.NewModuleDeclaration(
+ nil, /*modifiers*/
+ ast.KindNamespaceKeyword, /*keyword*/
+ typeNameOrNamespaceName,
+ body,
+ )
+ if nested {
+ jsDocNamespaceNode.Flags |= ast.NodeFlagsNestedNamespace
+ }
+ return p.finishNode(jsDocNamespaceNode, start)
+ }
+ if nested {
+ typeNameOrNamespaceName.Flags |= ast.NodeFlagsIdentifierIsInJSDocNamespace
+ }
+ return typeNameOrNamespaceName
+}
+
func (p *Parser) parseTypedefTag(start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node {
typeExpression := p.tryParseTypeExpression()
p.skipWhitespaceOrAsterisk()
- fullName := p.parseJSDocIdentifierName(diagnostics.Identifier_expected)
+ fullName := p.parseJSDocTypeNameWithNamespace(false /*nested*/)
+ if fullName == nil {
+ fullName = p.parseJSDocIdentifierName(diagnostics.Identifier_expected)
+ }
p.skipWhitespace()
comment := p.parseTagComments(indent, nil)
@@ -1106,7 +1134,10 @@ func (p *Parser) parseJSDocSignature(start int, indent int) *ast.Node {
}
func (p *Parser) parseCallbackTag(start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node {
- fullName := p.parseJSDocIdentifierName(diagnostics.Identifier_expected)
+ fullName := p.parseJSDocTypeNameWithNamespace(false /*nested*/)
+ if fullName == nil {
+ fullName = p.parseJSDocIdentifierName(diagnostics.Identifier_expected)
+ }
p.skipWhitespace()
comment := p.parseTagComments(indent, nil)
typeExpression := p.parseJSDocSignature(p.nodePos(), indent)
diff --git a/internal/parser/reparser.go b/internal/parser/reparser.go
index 8a2aa2f158a..5346e596fc2 100644
--- a/internal/parser/reparser.go
+++ b/internal/parser/reparser.go
@@ -51,7 +51,13 @@ func (p *Parser) reparseUnhosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Nod
if typeExpression == nil {
break
}
- typeAlias := p.factory.NewJSTypeAliasDeclaration(nil, p.addDeepCloneReparse(tag.AsJSDocTypedefTag().Name()), nil, nil)
+ fullName := tag.Name()
+ isNamespace := fullName != nil && ast.IsModuleDeclaration(fullName)
+ var modifiers *ast.ModifierList
+ if isNamespace {
+ modifiers = p.createExportModifier(tag)
+ }
+ typeAlias := p.factory.NewJSTypeAliasDeclaration(modifiers, p.addDeepCloneReparse(p.getInnermostNameOfJSDocNamespace(fullName)), nil, nil)
typeAlias.AsTypeAliasDeclaration().TypeParameters = p.gatherTypeParameters(jsDoc, tag)
var t *ast.Node
switch typeExpression.Kind {
@@ -66,19 +72,27 @@ func (p *Parser) reparseUnhosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Nod
p.finishReparsedNode(typeAlias, tag)
p.jsdocInfos = append(p.jsdocInfos, JSDocInfo{parent: typeAlias, jsDocs: []*ast.Node{jsDoc}})
typeAlias.Flags |= ast.NodeFlagsHasJSDoc
- p.reparseList = append(p.reparseList, typeAlias)
+ result := p.wrapInJSDocNamespace(fullName, typeAlias, false /*nested*/)
+ p.reparseList = append(p.reparseList, result)
case ast.KindJSDocCallbackTag:
- callbackTag := tag.AsJSDocCallbackTag()
- if callbackTag.TypeExpression == nil {
+ typeExpression := tag.TypeExpression()
+ if typeExpression == nil {
break
}
- functionType := p.reparseJSDocSignature(callbackTag.TypeExpression, tag, jsDoc, tag, nil)
- typeAlias := p.factory.NewJSTypeAliasDeclaration(nil, p.addDeepCloneReparse(callbackTag.FullName), nil, functionType)
+ fullName := tag.Name()
+ isNamespace := fullName != nil && ast.IsModuleDeclaration(fullName)
+ var modifiers *ast.ModifierList
+ if isNamespace {
+ modifiers = p.createExportModifier(tag)
+ }
+ functionType := p.reparseJSDocSignature(typeExpression, tag, jsDoc, tag, nil)
+ typeAlias := p.factory.NewJSTypeAliasDeclaration(modifiers, p.addDeepCloneReparse(p.getInnermostNameOfJSDocNamespace(fullName)), nil, functionType)
typeAlias.AsTypeAliasDeclaration().TypeParameters = p.gatherTypeParameters(jsDoc, tag)
p.finishReparsedNode(typeAlias, tag)
p.jsdocInfos = append(p.jsdocInfos, JSDocInfo{parent: typeAlias, jsDocs: []*ast.Node{jsDoc}})
typeAlias.Flags |= ast.NodeFlagsHasJSDoc
- p.reparseList = append(p.reparseList, typeAlias)
+ result := p.wrapInJSDocNamespace(fullName, typeAlias, false /*nested*/)
+ p.reparseList = append(p.reparseList, result)
case ast.KindJSDocImportTag:
importTag := tag.AsJSDocImportTag()
if importTag.ImportClause == nil {
@@ -621,3 +635,57 @@ func getClassLikeData(parent *ast.Node) *ast.ClassLikeBase {
}
return class
}
+
+func (p *Parser) createExportModifier(locationNode *ast.Node) *ast.ModifierList {
+ exportModifier := p.factory.NewModifier(ast.KindExportKeyword)
+ exportModifier.Loc = locationNode.Loc
+ exportModifier.Flags = p.contextFlags | ast.NodeFlagsReparsed
+ nodes := p.nodeSliceArena.NewSlice1(exportModifier)
+ return p.newModifierList(locationNode.Loc, nodes)
+}
+
+// getInnermostNameOfJSDocNamespace returns the innermost identifier from a
+// JSDoc namespace chain (ModuleDeclaration). For a simple identifier, it returns
+// the identifier itself. For "A.B.C", it returns the identifier "C".
+func (p *Parser) getInnermostNameOfJSDocNamespace(fullName *ast.Node) *ast.Node {
+ if fullName == nil {
+ return nil
+ }
+ for fullName.Kind == ast.KindModuleDeclaration {
+ body := fullName.AsModuleDeclaration().Body
+ if body == nil {
+ return fullName.Name()
+ }
+ fullName = body
+ }
+ return fullName
+}
+
+// wrapInJSDocNamespace wraps a statement (typically a type alias) in namespace
+// declarations corresponding to a JSDoc dotted name. For example, given name
+// "A.B.C" and a type alias for C, this produces:
+//
+// namespace A { namespace B { type C = ... } }
+//
+// If the name is a simple identifier (not a ModuleDeclaration), it returns the
+// statement as-is.
+func (p *Parser) wrapInJSDocNamespace(fullName *ast.Node, statement *ast.Node, nested bool) *ast.Node {
+ if fullName == nil || !ast.IsModuleDeclaration(fullName) {
+ return statement
+ }
+ // Recursively wrap from outermost to innermost. Inner namespaces always get an export modifier
+ // so members are accessible via dotted access from outside. The outermost namespace is treated as
+ // exported only in module files via IsImplicitlyExportedJSDocDeclaration (in the binder), so it
+ // does not get an explicit export modifier here.
+ wrapped := p.wrapInJSDocNamespace(fullName.Body(), statement, true /*nested*/)
+ block := p.factory.NewModuleBlock(p.newNodeList(fullName.Loc, p.nodeSliceArena.NewSlice1(wrapped)))
+ p.finishReparsedNode(block, fullName)
+ var modifiers *ast.ModifierList
+ if nested {
+ modifiers = p.createExportModifier(fullName)
+ }
+ result := p.factory.NewModuleDeclaration(modifiers, ast.KindNamespaceKeyword, p.addDeepCloneReparse(fullName.Name()), block)
+ p.finishReparsedNode(result, fullName)
+ p.reparsedClones = append(p.reparsedClones, result)
+ return result
+}
diff --git a/internal/transformers/declarations/transform.go b/internal/transformers/declarations/transform.go
index 16d558fecab..3afb5c2a4d8 100644
--- a/internal/transformers/declarations/transform.go
+++ b/internal/transformers/declarations/transform.go
@@ -1892,7 +1892,7 @@ func (tx *DeclarationTransformer) ensureModifierFlags(node *ast.Node) ast.Modifi
mask ^= ast.ModifierFlagsAmbient
additions = ast.ModifierFlagsNone
}
- if ast.IsImplicitlyExportedJSTypeAlias(node) {
+ if ast.IsImplicitlyExportedJSDocDeclaration(node) {
additions |= ast.ModifierFlagsExport
}
return maskModifierFlags(tx.host, node, mask, additions)
diff --git a/testdata/baselines/reference/compiler/jsDocTypedefTagNamespace.js b/testdata/baselines/reference/compiler/jsDocTypedefTagNamespace.js
new file mode 100644
index 00000000000..a8a44686f67
--- /dev/null
+++ b/testdata/baselines/reference/compiler/jsDocTypedefTagNamespace.js
@@ -0,0 +1,68 @@
+//// [tests/cases/compiler/jsDocTypedefTagNamespace.ts] ////
+
+//// [a.js]
+/** @typedef {number} NS.T */
+/** @typedef {string} NS.U */
+
+/** @type {NS.T} */
+const x = 1;
+
+/** @type {NS.U} */
+const y = "hello";
+
+//// [b.js]
+/** @typedef {{age: number}} A.B.MyType */
+
+/** @type {A.B.MyType} */
+const z = { age: 42 };
+
+//// [c.js]
+/** @callback NS.MyCallback
+ * @param {string} name
+ * @returns {void}
+ */
+
+/** @type {NS.MyCallback} */
+const f = (name) => {};
+
+//// [d.js]
+/** @typedef {number} M.T */
+
+/** @type {M.T} */
+export const xd = 1;
+
+//// [e.js]
+import { xd } from "./d.js";
+/** @type {import("./d.js").M.T} */
+export const ed = xd;
+
+
+//// [a.js]
+"use strict";
+/** @typedef {number} NS.T */
+/** @typedef {string} NS.U */
+/** @type {NS.T} */
+const x = 1;
+/** @type {NS.U} */
+const y = "hello";
+//// [b.js]
+"use strict";
+/** @typedef {{age: number}} A.B.MyType */
+/** @type {A.B.MyType} */
+const z = { age: 42 };
+//// [c.js]
+"use strict";
+/** @callback NS.MyCallback
+ * @param {string} name
+ * @returns {void}
+ */
+/** @type {NS.MyCallback} */
+const f = (name) => { };
+//// [d.js]
+/** @typedef {number} M.T */
+/** @type {M.T} */
+export const xd = 1;
+//// [e.js]
+import { xd } from "./d.js";
+/** @type {import("./d.js").M.T} */
+export const ed = xd;
diff --git a/testdata/baselines/reference/compiler/jsDocTypedefTagNamespace.symbols b/testdata/baselines/reference/compiler/jsDocTypedefTagNamespace.symbols
new file mode 100644
index 00000000000..0b6035d6dae
--- /dev/null
+++ b/testdata/baselines/reference/compiler/jsDocTypedefTagNamespace.symbols
@@ -0,0 +1,49 @@
+//// [tests/cases/compiler/jsDocTypedefTagNamespace.ts] ////
+
+=== a.js ===
+/** @typedef {number} NS.T */
+/** @typedef {string} NS.U */
+
+/** @type {NS.T} */
+const x = 1;
+>x : Symbol(x, Decl(a.js, 4, 5))
+
+/** @type {NS.U} */
+const y = "hello";
+>y : Symbol(y, Decl(a.js, 7, 5))
+
+=== b.js ===
+/** @typedef {{age: number}} A.B.MyType */
+
+/** @type {A.B.MyType} */
+const z = { age: 42 };
+>z : Symbol(z, Decl(b.js, 3, 5))
+>age : Symbol(age, Decl(b.js, 3, 11))
+
+=== c.js ===
+/** @callback NS.MyCallback
+ * @param {string} name
+ * @returns {void}
+ */
+
+/** @type {NS.MyCallback} */
+const f = (name) => {};
+>f : Symbol(f, Decl(c.js, 6, 5))
+>name : Symbol(name, Decl(c.js, 6, 11))
+
+=== d.js ===
+/** @typedef {number} M.T */
+
+/** @type {M.T} */
+export const xd = 1;
+>xd : Symbol(xd, Decl(d.js, 3, 12))
+
+=== e.js ===
+import { xd } from "./d.js";
+>xd : Symbol(xd, Decl(e.js, 0, 8))
+
+/** @type {import("./d.js").M.T} */
+export const ed = xd;
+>ed : Symbol(ed, Decl(e.js, 2, 12))
+>xd : Symbol(xd, Decl(e.js, 0, 8))
+
diff --git a/testdata/baselines/reference/compiler/jsDocTypedefTagNamespace.types b/testdata/baselines/reference/compiler/jsDocTypedefTagNamespace.types
new file mode 100644
index 00000000000..a65a589683d
--- /dev/null
+++ b/testdata/baselines/reference/compiler/jsDocTypedefTagNamespace.types
@@ -0,0 +1,55 @@
+//// [tests/cases/compiler/jsDocTypedefTagNamespace.ts] ////
+
+=== a.js ===
+/** @typedef {number} NS.T */
+/** @typedef {string} NS.U */
+
+/** @type {NS.T} */
+const x = 1;
+>x : number
+>1 : 1
+
+/** @type {NS.U} */
+const y = "hello";
+>y : string
+>"hello" : "hello"
+
+=== b.js ===
+/** @typedef {{age: number}} A.B.MyType */
+
+/** @type {A.B.MyType} */
+const z = { age: 42 };
+>z : A.B.MyType
+>{ age: 42 } : { age: number; }
+>age : number
+>42 : 42
+
+=== c.js ===
+/** @callback NS.MyCallback
+ * @param {string} name
+ * @returns {void}
+ */
+
+/** @type {NS.MyCallback} */
+const f = (name) => {};
+>f : NS.MyCallback
+>(name) => {} : (name: string) => void
+>name : string
+
+=== d.js ===
+/** @typedef {number} M.T */
+
+/** @type {M.T} */
+export const xd = 1;
+>xd : number
+>1 : 1
+
+=== e.js ===
+import { xd } from "./d.js";
+>xd : number
+
+/** @type {import("./d.js").M.T} */
+export const ed = xd;
+>ed : number
+>xd : number
+
diff --git a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.errors.txt b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.errors.txt
index 4ec5325f9f6..9bf6de47fce 100644
--- a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.errors.txt
+++ b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.errors.txt
@@ -1,7 +1,6 @@
enumDef.js(14,21): error TS1003: Identifier expected.
-index.js(4,17): error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
-index.js(13,11): error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
-index.js(18,11): error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
+index.js(4,17): error TS2749: 'Host.UserMetrics.Action' refers to a value, but is being used as a type here. Did you mean 'typeof Host.UserMetrics.Action'?
+index.js(18,11): error TS2749: 'Host.UserMetrics.Blah' refers to a value, but is being used as a type here. Did you mean 'typeof Host.UserMetrics.Blah'?
==== enumDef.js (1 errors) ====
@@ -26,13 +25,13 @@ index.js(18,11): error TS2702: 'Host' only refers to a type, but is being used a
Host.UserMetrics.Blah = {
x: 12
}
-==== index.js (3 errors) ====
+==== index.js (2 errors) ====
var Other = {};
Other.Cls = class {
/**
* @param {!Host.UserMetrics.Action} p
- ~~~~
-!!! error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
+ ~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2749: 'Host.UserMetrics.Action' refers to a value, but is being used as a type here. Did you mean 'typeof Host.UserMetrics.Action'?
*/
method(p) {}
usage() {
@@ -42,15 +41,13 @@ index.js(18,11): error TS2702: 'Host' only refers to a type, but is being used a
/**
* @type {Host.UserMetrics.Bargh}
- ~~~~
-!!! error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
*/
var x = "ok";
/**
* @type {Host.UserMetrics.Blah}
- ~~~~
-!!! error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
+ ~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2749: 'Host.UserMetrics.Blah' refers to a value, but is being used as a type here. Did you mean 'typeof Host.UserMetrics.Blah'?
*/
var y = "ok";
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.errors.txt.diff
index de61884fc1d..4ee98634e71 100644
--- a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.errors.txt.diff
+++ b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.errors.txt.diff
@@ -3,9 +3,8 @@
@@= skipped -0, +0 lines =@@
-
+enumDef.js(14,21): error TS1003: Identifier expected.
-+index.js(4,17): error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
-+index.js(13,11): error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
-+index.js(18,11): error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
++index.js(4,17): error TS2749: 'Host.UserMetrics.Action' refers to a value, but is being used as a type here. Did you mean 'typeof Host.UserMetrics.Action'?
++index.js(18,11): error TS2749: 'Host.UserMetrics.Blah' refers to a value, but is being used as a type here. Did you mean 'typeof Host.UserMetrics.Blah'?
+
+
+==== enumDef.js (1 errors) ====
@@ -30,13 +29,13 @@
+ Host.UserMetrics.Blah = {
+ x: 12
+ }
-+==== index.js (3 errors) ====
++==== index.js (2 errors) ====
+ var Other = {};
+ Other.Cls = class {
+ /**
+ * @param {!Host.UserMetrics.Action} p
-+ ~~~~
-+!!! error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
++ ~~~~~~~~~~~~~~~~~~~~~~~
++!!! error TS2749: 'Host.UserMetrics.Action' refers to a value, but is being used as a type here. Did you mean 'typeof Host.UserMetrics.Action'?
+ */
+ method(p) {}
+ usage() {
@@ -46,15 +45,13 @@
+
+ /**
+ * @type {Host.UserMetrics.Bargh}
-+ ~~~~
-+!!! error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
+ */
+ var x = "ok";
+
+ /**
+ * @type {Host.UserMetrics.Blah}
-+ ~~~~
-+!!! error TS2702: 'Host' only refers to a type, but is being used as a namespace here.
++ ~~~~~~~~~~~~~~~~~~~~~
++!!! error TS2749: 'Host.UserMetrics.Blah' refers to a value, but is being used as a type here. Did you mean 'typeof Host.UserMetrics.Blah'?
+ */
+ var y = "ok";
+
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.symbols b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.symbols
index bf0e0ccf1e6..2ea932517e4 100644
--- a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.symbols
+++ b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.symbols
@@ -2,18 +2,18 @@
=== enumDef.js ===
var Host = {};
->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
Host.UserMetrics = {};
>Host.UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
>UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
/** @enum {number} */
Host.UserMetrics.Action = {
>Host.UserMetrics.Action : Symbol(Action, Decl(enumDef.js, 1, 22))
>Host.UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
>UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
>Action : Symbol(Action, Decl(enumDef.js, 1, 22))
@@ -39,7 +39,7 @@ Host.UserMetrics.Action = {
Host.UserMetrics.Blah = {
>Host.UserMetrics.Blah : Symbol(Blah, Decl(enumDef.js, 8, 2))
>Host.UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
>UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
>Blah : Symbol(Blah, Decl(enumDef.js, 8, 2))
@@ -72,7 +72,7 @@ Other.Cls = class {
>Host.UserMetrics.Action.WindowDocked : Symbol(WindowDocked, Decl(enumDef.js, 3, 27))
>Host.UserMetrics.Action : Symbol(Action, Decl(enumDef.js, 1, 22))
>Host.UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
>UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
>Action : Symbol(Action, Decl(enumDef.js, 1, 22))
>WindowDocked : Symbol(WindowDocked, Decl(enumDef.js, 3, 27))
diff --git a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.symbols.diff b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.symbols.diff
index cacd083c2b3..bc49b59b24a 100644
--- a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.symbols.diff
+++ b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.symbols.diff
@@ -5,14 +5,14 @@
=== enumDef.js ===
var Host = {};
->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 10, 21))
-+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
++>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
Host.UserMetrics = {};
->Host.UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26))
->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 10, 21))
->UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26))
+>Host.UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
-+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
++>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
+>UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
/** @enum {number} */
@@ -24,7 +24,7 @@
->Action : Symbol(Host.UserMetrics.Action, Decl(enumDef.js, 1, 22), Decl(enumDef.js, 3, 17), Decl(enumDef.js, 2, 4))
+>Host.UserMetrics.Action : Symbol(Action, Decl(enumDef.js, 1, 22))
+>Host.UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
-+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
++>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
+>UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
+>Action : Symbol(Action, Decl(enumDef.js, 1, 22))
@@ -41,7 +41,7 @@
->Blah : Symbol(Host.UserMetrics.Blah, Decl(enumDef.js, 8, 2), Decl(enumDef.js, 15, 17), Decl(enumDef.js, 13, 3))
+>Host.UserMetrics.Blah : Symbol(Blah, Decl(enumDef.js, 8, 2))
+>Host.UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
-+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
++>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
+>UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
+>Blah : Symbol(Blah, Decl(enumDef.js, 8, 2))
@@ -74,7 +74,7 @@
->Action : Symbol(Host.UserMetrics.Action, Decl(enumDef.js, 1, 22), Decl(enumDef.js, 3, 17), Decl(enumDef.js, 2, 4))
+>Host.UserMetrics.Action : Symbol(Action, Decl(enumDef.js, 1, 22))
+>Host.UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
-+>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 3))
++>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 10, 21))
+>UserMetrics : Symbol(UserMetrics, Decl(enumDef.js, 0, 14))
+>Action : Symbol(Action, Decl(enumDef.js, 1, 22))
>WindowDocked : Symbol(WindowDocked, Decl(enumDef.js, 3, 27))
diff --git a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.types b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.types
index 21bb730b00a..3e8bcc05e20 100644
--- a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.types
+++ b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.types
@@ -99,7 +99,7 @@ Other.Cls = class {
* @type {Host.UserMetrics.Bargh}
*/
var x = "ok";
->x : Host.UserMetrics.Bargh
+>x : string
>"ok" : "ok"
/**
diff --git a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.types.diff b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.types.diff
index 691473114ed..4b403f3e62e 100644
--- a/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.types.diff
+++ b/testdata/baselines/reference/submodule/compiler/jsEnumCrossFileExport.types.diff
@@ -86,15 +86,7 @@
>Action : { WindowDocked: number; WindowUndocked: number; ScriptsBreakpointSet: number; TimelineStarted: number; }
>WindowDocked : number
}
-@@= skipped -12, +12 lines =@@
- * @type {Host.UserMetrics.Bargh}
- */
- var x = "ok";
-->x : string
-+>x : Host.UserMetrics.Bargh
- >"ok" : "ok"
-
- /**
+@@= skipped -19, +19 lines =@@
* @type {Host.UserMetrics.Blah}
*/
var y = "ok";
diff --git a/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.errors.txt b/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.errors.txt
deleted file mode 100644
index a0dd808ea5e..00000000000
--- a/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.errors.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-namespaced.js(8,12): error TS2702: 'NS' only refers to a type, but is being used as a namespace here.
-namespaced.js(8,12): error TS8030: A JSDoc '@type' tag on a function must have a signature with the correct number of arguments.
-namespaced.js(9,12): error TS7006: Parameter 'space' implicitly has an 'any' type.
-namespaced.js(9,19): error TS7006: Parameter 'peace' implicitly has an 'any' type.
-
-
-==== namespaced.js (4 errors) ====
- /**
- * @callback NS.Nested.Inner
- * @param {Object} space - spaaaaaaaaace
- * @param {Object} peace - peaaaaaaaaace
- * @return {string | number}
- */
- var x = 1;
- /** @type {NS.Nested.Inner} */
- ~~
-!!! error TS2702: 'NS' only refers to a type, but is being used as a namespace here.
- ~~~~~~~~~~~~~~~
-!!! error TS8030: A JSDoc '@type' tag on a function must have a signature with the correct number of arguments.
- function f(space, peace) {
- ~~~~~
-!!! error TS7006: Parameter 'space' implicitly has an 'any' type.
- ~~~~~
-!!! error TS7006: Parameter 'peace' implicitly has an 'any' type.
- return '1'
- }
-
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.errors.txt.diff b/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.errors.txt.diff
deleted file mode 100644
index d965d4f8a8a..00000000000
--- a/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.errors.txt.diff
+++ /dev/null
@@ -1,31 +0,0 @@
---- old.callbackTagNamespace.errors.txt
-+++ new.callbackTagNamespace.errors.txt
-@@= skipped -0, +0 lines =@@
--
-+namespaced.js(8,12): error TS2702: 'NS' only refers to a type, but is being used as a namespace here.
-+namespaced.js(8,12): error TS8030: A JSDoc '@type' tag on a function must have a signature with the correct number of arguments.
-+namespaced.js(9,12): error TS7006: Parameter 'space' implicitly has an 'any' type.
-+namespaced.js(9,19): error TS7006: Parameter 'peace' implicitly has an 'any' type.
-+
-+
-+==== namespaced.js (4 errors) ====
-+ /**
-+ * @callback NS.Nested.Inner
-+ * @param {Object} space - spaaaaaaaaace
-+ * @param {Object} peace - peaaaaaaaaace
-+ * @return {string | number}
-+ */
-+ var x = 1;
-+ /** @type {NS.Nested.Inner} */
-+ ~~
-+!!! error TS2702: 'NS' only refers to a type, but is being used as a namespace here.
-+ ~~~~~~~~~~~~~~~
-+!!! error TS8030: A JSDoc '@type' tag on a function must have a signature with the correct number of arguments.
-+ function f(space, peace) {
-+ ~~~~~
-+!!! error TS7006: Parameter 'space' implicitly has an 'any' type.
-+ ~~~~~
-+!!! error TS7006: Parameter 'peace' implicitly has an 'any' type.
-+ return '1'
-+ }
-+
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.types b/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.types
index 5524b298521..a4a2989eee7 100644
--- a/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.types
+++ b/testdata/baselines/reference/submodule/conformance/callbackTagNamespace.types
@@ -13,9 +13,9 @@ var x = 1;
/** @type {NS.Nested.Inner} */
function f(space, peace) {
->f : (space: any, peace: any) => string
->space : any
->peace : any
+>f : (space: Object, peace: Object) => string | number
+>space : Object
+>peace : Object
return '1'
>'1' : "1"
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.errors.txt b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.errors.txt
deleted file mode 100644
index c783e6e28da..00000000000
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.errors.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-file.js(10,51): error TS2300: Duplicate identifier 'myTypes'.
-file.js(13,13): error TS2300: Duplicate identifier 'myTypes'.
-file.js(14,15): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-file.js(18,15): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-file.js(18,39): error TS2300: Duplicate identifier 'myTypes'.
-file.js(20,9): error TS2300: Duplicate identifier 'myTypes'.
-file2.js(12,23): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-file2.js(17,12): error TS2702: 'testFnTypes' only refers to a type, but is being used as a namespace here.
-
-
-==== file.js (6 errors) ====
- /**
- * @namespace myTypes
- * @global
- * @type {Object}
- */
- const myTypes = {
- // SOME PROPS HERE
- };
-
- /** @typedef {string|RegExp|Array} myTypes.typeA */
- ~~~~~~~
-!!! error TS2300: Duplicate identifier 'myTypes'.
-
- /**
- * @typedef myTypes.typeB
- ~~~~~~~
-!!! error TS2300: Duplicate identifier 'myTypes'.
- * @property {myTypes.typeA} prop1 - Prop 1.
- ~~~~~~~
-!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
- * @property {string} prop2 - Prop 2.
- */
-
- /** @typedef {myTypes.typeB|Function} myTypes.typeC */
- ~~~~~~~
-!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
- ~~~~~~~
-!!! error TS2300: Duplicate identifier 'myTypes'.
-
- export {myTypes};
- ~~~~~~~
-!!! error TS2300: Duplicate identifier 'myTypes'.
-==== file2.js (2 errors) ====
- import {myTypes} from './file.js';
-
- /**
- * @namespace testFnTypes
- * @global
- * @type {Object}
- */
- const testFnTypes = {
- // SOME PROPS HERE
- };
-
- /** @typedef {boolean|myTypes.typeC} testFnTypes.input */
- ~~~~~~~
-!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-
- /**
- * @function testFn
- * @description A test function.
- * @param {testFnTypes.input} input - Input.
- ~~~~~~~~~~~
-!!! error TS2702: 'testFnTypes' only refers to a type, but is being used as a namespace here.
- * @returns {number|null} Result.
- */
- function testFn(input) {
- if (typeof input === 'number') {
- return 2 * input;
- } else {
- return null;
- }
- }
-
- export {testFn, testFnTypes};
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.errors.txt.diff b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.errors.txt.diff
index 73787e78d74..801fbe1cb42 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.errors.txt.diff
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.errors.txt.diff
@@ -5,67 +5,55 @@
-
-
-==== file.js (0 errors) ====
-+file.js(10,51): error TS2300: Duplicate identifier 'myTypes'.
-+file.js(13,13): error TS2300: Duplicate identifier 'myTypes'.
-+file.js(14,15): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+file.js(18,15): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+file.js(18,39): error TS2300: Duplicate identifier 'myTypes'.
-+file.js(20,9): error TS2300: Duplicate identifier 'myTypes'.
-+file2.js(12,23): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+file2.js(17,12): error TS2702: 'testFnTypes' only refers to a type, but is being used as a namespace here.
-+
-+
-+==== file.js (6 errors) ====
- /**
- * @namespace myTypes
- * @global
-@@= skipped -11, +18 lines =@@
- };
-
- /** @typedef {string|RegExp|Array} myTypes.typeA */
-+ ~~~~~~~
-+!!! error TS2300: Duplicate identifier 'myTypes'.
-
- /**
- * @typedef myTypes.typeB
-+ ~~~~~~~
-+!!! error TS2300: Duplicate identifier 'myTypes'.
- * @property {myTypes.typeA} prop1 - Prop 1.
-+ ~~~~~~~
-+!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
- * @property {string} prop2 - Prop 2.
- */
-
- /** @typedef {myTypes.typeB|Function} myTypes.typeC */
-+ ~~~~~~~
-+!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+ ~~~~~~~
-+!!! error TS2300: Duplicate identifier 'myTypes'.
-
- export {myTypes};
+- /**
+- * @namespace myTypes
+- * @global
+- * @type {Object}
+- */
+- const myTypes = {
+- // SOME PROPS HERE
+- };
+-
+- /** @typedef {string|RegExp|Array} myTypes.typeA */
+-
+- /**
+- * @typedef myTypes.typeB
+- * @property {myTypes.typeA} prop1 - Prop 1.
+- * @property {string} prop2 - Prop 2.
+- */
+-
+- /** @typedef {myTypes.typeB|Function} myTypes.typeC */
+-
+- export {myTypes};
-==== file2.js (1 errors) ====
- import {myTypes} from './file.js';
- ~~~~~~~
+- ~~~~~~~
-!!! error TS18042: 'myTypes' is a type and cannot be imported in JavaScript files. Use 'import("./file.js").myTypes' in a JSDoc type annotation.
-+!!! error TS2300: Duplicate identifier 'myTypes'.
-+==== file2.js (2 errors) ====
-+ import {myTypes} from './file.js';
-
- /**
- * @namespace testFnTypes
-@@= skipped -25, +35 lines =@@
- };
-
- /** @typedef {boolean|myTypes.typeC} testFnTypes.input */
-+ ~~~~~~~
-+!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-
- /**
- * @function testFn
- * @description A test function.
- * @param {testFnTypes.input} input - Input.
-+ ~~~~~~~~~~~
-+!!! error TS2702: 'testFnTypes' only refers to a type, but is being used as a namespace here.
- * @returns {number|null} Result.
- */
- function testFn(input) {
\ No newline at end of file
+-
+- /**
+- * @namespace testFnTypes
+- * @global
+- * @type {Object}
+- */
+- const testFnTypes = {
+- // SOME PROPS HERE
+- };
+-
+- /** @typedef {boolean|myTypes.typeC} testFnTypes.input */
+-
+- /**
+- * @function testFn
+- * @description A test function.
+- * @param {testFnTypes.input} input - Input.
+- * @returns {number|null} Result.
+- */
+- function testFn(input) {
+- if (typeof input === 'number') {
+- return 2 * input;
+- } else {
+- return null;
+- }
+- }
+-
+- export {testFn, testFnTypes};
++
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.js b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.js
index 4505f2cf784..1cc99f36c22 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.js
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.js
@@ -60,12 +60,18 @@ export {testFn, testFnTypes};
* @type {Object}
*/
declare const myTypes: Record;
-export type myTypes = string | RegExp | Array;
-export type myTypes = {
- prop1: myTypes.typeA;
- prop2: string;
-};
-export type myTypes = myTypes.typeB | Function;
+export declare namespace myTypes {
+ export type typeA = string | RegExp | Array;
+}
+export declare namespace myTypes {
+ export type typeB = {
+ prop1: myTypes.typeA;
+ prop2: string;
+ };
+}
+export declare namespace myTypes {
+ export type typeC = myTypes.typeB | Function;
+}
/** @typedef {string|RegExp|Array} myTypes.typeA */
/**
* @typedef myTypes.typeB
@@ -75,13 +81,16 @@ export type myTypes = myTypes.typeB | Function;
/** @typedef {myTypes.typeB|Function} myTypes.typeC */
export { myTypes };
//// [file2.d.ts]
+import { myTypes } from './file.js';
/**
* @namespace testFnTypes
* @global
* @type {Object}
*/
declare const testFnTypes: Record;
-export type testFnTypes = boolean | myTypes.typeC;
+export declare namespace testFnTypes {
+ export type input = boolean | myTypes.typeC;
+}
/** @typedef {boolean|myTypes.typeC} testFnTypes.input */
/**
* @function testFn
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.symbols b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.symbols
index a5c956f0fbb..7ebec4dad29 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.symbols
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.symbols
@@ -7,7 +7,7 @@
* @type {Object}
*/
const myTypes = {
->myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 4), Decl(file.js, 12, 3), Decl(file.js, 17, 4))
+>myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38))
// SOME PROPS HERE
};
@@ -23,7 +23,7 @@ const myTypes = {
/** @typedef {myTypes.typeB|Function} myTypes.typeC */
export {myTypes};
->myTypes : Symbol(myTypes, Decl(file.js, 19, 8), Decl(file.js, 9, 4))
+>myTypes : Symbol(myTypes, Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38), Decl(file.js, 19, 8))
=== file2.js ===
import {myTypes} from './file.js';
@@ -35,7 +35,7 @@ import {myTypes} from './file.js';
* @type {Object}
*/
const testFnTypes = {
->testFnTypes : Symbol(testFnTypes, Decl(file2.js, 7, 5), Decl(file2.js, 11, 4))
+>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 7, 5), Decl(file2.js, 11, 37))
// SOME PROPS HERE
};
@@ -65,5 +65,5 @@ function testFn(input) {
export {testFn, testFnTypes};
>testFn : Symbol(testFn, Decl(file2.js, 27, 8))
->testFnTypes : Symbol(testFnTypes, Decl(file2.js, 27, 15), Decl(file2.js, 11, 4))
+>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 11, 37), Decl(file2.js, 27, 15))
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.symbols.diff b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.symbols.diff
index 10d8b008faa..fde4707f8b3 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.symbols.diff
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.symbols.diff
@@ -1,35 +1,17 @@
--- old.jsDeclarationsImportAliasExposedWithinNamespace.symbols
+++ new.jsDeclarationsImportAliasExposedWithinNamespace.symbols
-@@= skipped -6, +6 lines =@@
- * @type {Object}
- */
- const myTypes = {
-->myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38))
-+>myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 4), Decl(file.js, 12, 3), Decl(file.js, 17, 4))
-
- // SOME PROPS HERE
- };
-@@= skipped -16, +16 lines =@@
+@@= skipped -22, +22 lines =@@
/** @typedef {myTypes.typeB|Function} myTypes.typeC */
export {myTypes};
->myTypes : Symbol(myTypes, Decl(file.js, 19, 8), Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38))
-+>myTypes : Symbol(myTypes, Decl(file.js, 19, 8), Decl(file.js, 9, 4))
++>myTypes : Symbol(myTypes, Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38), Decl(file.js, 19, 8))
=== file2.js ===
import {myTypes} from './file.js';
-@@= skipped -12, +12 lines =@@
- * @type {Object}
- */
- const testFnTypes = {
-->testFnTypes : Symbol(testFnTypes, Decl(file2.js, 7, 5), Decl(file2.js, 11, 37))
-+>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 7, 5), Decl(file2.js, 11, 4))
-
- // SOME PROPS HERE
- };
-@@= skipped -30, +30 lines =@@
+@@= skipped -42, +42 lines =@@
export {testFn, testFnTypes};
>testFn : Symbol(testFn, Decl(file2.js, 27, 8))
->testFnTypes : Symbol(testFnTypes, Decl(file2.js, 27, 15), Decl(file2.js, 11, 37))
-+>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 27, 15), Decl(file2.js, 11, 4))
++>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 11, 37), Decl(file2.js, 27, 15))
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.types b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.types
index 77ef5568944..92e2252fae3 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.types
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.types
@@ -63,7 +63,7 @@ function testFn(input) {
return 2 * input;
>2 * input : number
>2 : 2
->input : number
+>input : never
} else {
return null;
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.types.diff b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.types.diff
index ea4844ed768..b85bc7ba779 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.types.diff
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespace.types.diff
@@ -47,13 +47,6 @@
>'number' : "number"
return 2 * input;
- >2 * input : number
- >2 : 2
-->input : never
-+>input : number
-
- } else {
- return null;
@@= skipped -20, +20 lines =@@
export {testFn, testFnTypes};
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.errors.txt b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.errors.txt
deleted file mode 100644
index fbe1b871df2..00000000000
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.errors.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-file.js(10,51): error TS2300: Duplicate identifier 'myTypes'.
-file.js(13,13): error TS2300: Duplicate identifier 'myTypes'.
-file.js(14,15): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-file.js(18,15): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-file.js(18,39): error TS2300: Duplicate identifier 'myTypes'.
-file.js(20,9): error TS2300: Duplicate identifier 'myTypes'.
-file2.js(12,23): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-file2.js(17,12): error TS2702: 'testFnTypes' only refers to a type, but is being used as a namespace here.
-
-
-==== file2.js (2 errors) ====
- const {myTypes} = require('./file.js');
-
- /**
- * @namespace testFnTypes
- * @global
- * @type {Object}
- */
- const testFnTypes = {
- // SOME PROPS HERE
- };
-
- /** @typedef {boolean|myTypes.typeC} testFnTypes.input */
- ~~~~~~~
-!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-
- /**
- * @function testFn
- * @description A test function.
- * @param {testFnTypes.input} input - Input.
- ~~~~~~~~~~~
-!!! error TS2702: 'testFnTypes' only refers to a type, but is being used as a namespace here.
- * @returns {number|null} Result.
- */
- function testFn(input) {
- if (typeof input === 'number') {
- return 2 * input;
- } else {
- return null;
- }
- }
-
- module.exports = {testFn, testFnTypes};
-==== file.js (6 errors) ====
- /**
- * @namespace myTypes
- * @global
- * @type {Object}
- */
- const myTypes = {
- // SOME PROPS HERE
- };
-
- /** @typedef {string|RegExp|Array} myTypes.typeA */
- ~~~~~~~
-!!! error TS2300: Duplicate identifier 'myTypes'.
-
- /**
- * @typedef myTypes.typeB
- ~~~~~~~
-!!! error TS2300: Duplicate identifier 'myTypes'.
- * @property {myTypes.typeA} prop1 - Prop 1.
- ~~~~~~~
-!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
- * @property {string} prop2 - Prop 2.
- */
-
- /** @typedef {myTypes.typeB|Function} myTypes.typeC */
- ~~~~~~~
-!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
- ~~~~~~~
-!!! error TS2300: Duplicate identifier 'myTypes'.
-
- exports.myTypes = myTypes;
- ~~~~~~~
-!!! error TS2300: Duplicate identifier 'myTypes'.
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.errors.txt.diff b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.errors.txt.diff
deleted file mode 100644
index 558506756a1..00000000000
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.errors.txt.diff
+++ /dev/null
@@ -1,80 +0,0 @@
---- old.jsDeclarationsImportAliasExposedWithinNamespaceCjs.errors.txt
-+++ new.jsDeclarationsImportAliasExposedWithinNamespaceCjs.errors.txt
-@@= skipped -0, +0 lines =@@
--
-+file.js(10,51): error TS2300: Duplicate identifier 'myTypes'.
-+file.js(13,13): error TS2300: Duplicate identifier 'myTypes'.
-+file.js(14,15): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+file.js(18,15): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+file.js(18,39): error TS2300: Duplicate identifier 'myTypes'.
-+file.js(20,9): error TS2300: Duplicate identifier 'myTypes'.
-+file2.js(12,23): error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+file2.js(17,12): error TS2702: 'testFnTypes' only refers to a type, but is being used as a namespace here.
-+
-+
-+==== file2.js (2 errors) ====
-+ const {myTypes} = require('./file.js');
-+
-+ /**
-+ * @namespace testFnTypes
-+ * @global
-+ * @type {Object}
-+ */
-+ const testFnTypes = {
-+ // SOME PROPS HERE
-+ };
-+
-+ /** @typedef {boolean|myTypes.typeC} testFnTypes.input */
-+ ~~~~~~~
-+!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+
-+ /**
-+ * @function testFn
-+ * @description A test function.
-+ * @param {testFnTypes.input} input - Input.
-+ ~~~~~~~~~~~
-+!!! error TS2702: 'testFnTypes' only refers to a type, but is being used as a namespace here.
-+ * @returns {number|null} Result.
-+ */
-+ function testFn(input) {
-+ if (typeof input === 'number') {
-+ return 2 * input;
-+ } else {
-+ return null;
-+ }
-+ }
-+
-+ module.exports = {testFn, testFnTypes};
-+==== file.js (6 errors) ====
-+ /**
-+ * @namespace myTypes
-+ * @global
-+ * @type {Object}
-+ */
-+ const myTypes = {
-+ // SOME PROPS HERE
-+ };
-+
-+ /** @typedef {string|RegExp|Array} myTypes.typeA */
-+ ~~~~~~~
-+!!! error TS2300: Duplicate identifier 'myTypes'.
-+
-+ /**
-+ * @typedef myTypes.typeB
-+ ~~~~~~~
-+!!! error TS2300: Duplicate identifier 'myTypes'.
-+ * @property {myTypes.typeA} prop1 - Prop 1.
-+ ~~~~~~~
-+!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+ * @property {string} prop2 - Prop 2.
-+ */
-+
-+ /** @typedef {myTypes.typeB|Function} myTypes.typeC */
-+ ~~~~~~~
-+!!! error TS2702: 'myTypes' only refers to a type, but is being used as a namespace here.
-+ ~~~~~~~
-+!!! error TS2300: Duplicate identifier 'myTypes'.
-+
-+ exports.myTypes = myTypes;
-+ ~~~~~~~
-+!!! error TS2300: Duplicate identifier 'myTypes'.
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.js b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.js
index 1c5f3a0fb90..c2c42cc8902 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.js
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.js
@@ -60,23 +60,30 @@ module.exports = {testFn, testFnTypes};
* @type {Object}
*/
declare const myTypes: Record;
-export type myTypes = string | RegExp | Array;
-export type myTypes = {
- prop1: myTypes.typeA;
- prop2: string;
-};
-export type myTypes = myTypes.typeB | Function;
-/** @typedef {string|RegExp|Array} myTypes.typeA */
+export declare namespace myTypes {
+ export type typeA = string | RegExp | Array;
+}
+export declare namespace myTypes {
+ export type typeB = {
+ prop1: myTypes.typeA;
+ prop2: string;
+ };
+}
+export declare namespace myTypes {
+ export type typeC = myTypes.typeB | Function;
+}
+export { myTypes };
+//// [file2.d.ts]
+import { myTypes } from './file.js';
/**
- * @typedef myTypes.typeB
- * @property {myTypes.typeA} prop1 - Prop 1.
- * @property {string} prop2 - Prop 2.
+ * @namespace testFnTypes
+ * @global
+ * @type {Object}
*/
-/** @typedef {myTypes.typeB|Function} myTypes.typeC */
-declare const _exported: Record;
-export { _exported as myTypes };
-//// [file2.d.ts]
-export type testFnTypes = boolean | myTypes.typeC;
+declare const testFnTypes: Record;
+export declare namespace testFnTypes {
+ export type input = boolean | myTypes.typeC;
+}
/** @typedef {boolean|myTypes.typeC} testFnTypes.input */
/**
* @function testFn
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols
index 6c12bfb9875..245b35c2992 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols
@@ -12,7 +12,7 @@ const {myTypes} = require('./file.js');
* @type {Object}
*/
const testFnTypes = {
->testFnTypes : Symbol(testFnTypes, Decl(file2.js, 7, 5), Decl(file2.js, 11, 4))
+>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 7, 5), Decl(file2.js, 11, 37))
// SOME PROPS HERE
};
@@ -54,7 +54,7 @@ module.exports = {testFn, testFnTypes};
* @type {Object}
*/
const myTypes = {
->myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 4), Decl(file.js, 12, 3), Decl(file.js, 17, 4))
+>myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38))
// SOME PROPS HERE
};
@@ -70,8 +70,8 @@ const myTypes = {
/** @typedef {myTypes.typeB|Function} myTypes.typeC */
exports.myTypes = myTypes;
->exports.myTypes : Symbol(myTypes, Decl(file.js, 7, 2), Decl(file.js, 9, 4))
+>exports.myTypes : Symbol(myTypes, Decl(file.js, 7, 2))
>exports : Symbol(exports, Decl(file.js, 0, 0))
->myTypes : Symbol(myTypes, Decl(file.js, 7, 2), Decl(file.js, 9, 4))
->myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 4), Decl(file.js, 12, 3), Decl(file.js, 17, 4))
+>myTypes : Symbol(myTypes, Decl(file.js, 7, 2))
+>myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38))
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols.diff b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols.diff
index 2b2c6108367..2ea49baa8d3 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols.diff
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols.diff
@@ -1,15 +1,6 @@
--- old.jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols
+++ new.jsDeclarationsImportAliasExposedWithinNamespaceCjs.symbols
-@@= skipped -11, +11 lines =@@
- * @type {Object}
- */
- const testFnTypes = {
-->testFnTypes : Symbol(testFnTypes, Decl(file2.js, 7, 5), Decl(file2.js, 11, 37))
-+>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 7, 5), Decl(file2.js, 11, 4))
-
- // SOME PROPS HERE
- };
-@@= skipped -29, +29 lines =@@
+@@= skipped -40, +40 lines =@@
}
module.exports = {testFn, testFnTypes};
@@ -22,24 +13,11 @@
>testFn : Symbol(testFn, Decl(file2.js, 27, 18))
>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 27, 25))
-@@= skipped -13, +13 lines =@@
- * @type {Object}
- */
- const myTypes = {
-->myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38))
-+>myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 4), Decl(file.js, 12, 3), Decl(file.js, 17, 4))
-
- // SOME PROPS HERE
- };
-@@= skipped -16, +16 lines =@@
- /** @typedef {myTypes.typeB|Function} myTypes.typeC */
+@@= skipped -30, +30 lines =@@
exports.myTypes = myTypes;
-->exports.myTypes : Symbol(myTypes, Decl(file.js, 7, 2))
+ >exports.myTypes : Symbol(myTypes, Decl(file.js, 7, 2))
->exports : Symbol(myTypes, Decl(file.js, 7, 2))
-->myTypes : Symbol(myTypes, Decl(file.js, 7, 2))
-->myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38))
-+>exports.myTypes : Symbol(myTypes, Decl(file.js, 7, 2), Decl(file.js, 9, 4))
+>exports : Symbol(exports, Decl(file.js, 0, 0))
-+>myTypes : Symbol(myTypes, Decl(file.js, 7, 2), Decl(file.js, 9, 4))
-+>myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 4), Decl(file.js, 12, 3), Decl(file.js, 17, 4))
+ >myTypes : Symbol(myTypes, Decl(file.js, 7, 2))
+ >myTypes : Symbol(myTypes, Decl(file.js, 5, 5), Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38))
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.types b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.types
index 7e82d30d011..808a140efad 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.types
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.types
@@ -40,7 +40,7 @@ function testFn(input) {
return 2 * input;
>2 * input : number
>2 : 2
->input : number
+>input : never
} else {
return null;
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.types.diff b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.types.diff
index adce25b35b4..ae6519267e5 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.types.diff
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.types.diff
@@ -33,13 +33,6 @@
>'number' : "number"
return 2 * input;
- >2 * input : number
- >2 : 2
-->input : never
-+>input : number
-
- } else {
- return null;
@@= skipped -19, +19 lines =@@
}
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.errors.txt b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.errors.txt
deleted file mode 100644
index 8634dc22596..00000000000
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.errors.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-file.js(2,29): error TS2694: Namespace '"mod1"' has no exported member 'Dotted'.
-
-
-==== file.js (1 errors) ====
- import { dummy } from './mod1'
- /** @type {import('./mod1').Dotted.Name} - should work */
- ~~~~~~
-!!! error TS2694: Namespace '"mod1"' has no exported member 'Dotted'.
- var dot2
-
-==== mod1.js (0 errors) ====
- /** @typedef {number} Dotted.Name */
- export var dummy = 1
-
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.errors.txt.diff b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.errors.txt.diff
deleted file mode 100644
index 3c6b8c3b2f0..00000000000
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.errors.txt.diff
+++ /dev/null
@@ -1,18 +0,0 @@
---- old.jsDeclarationsImportNamespacedType.errors.txt
-+++ new.jsDeclarationsImportNamespacedType.errors.txt
-@@= skipped -0, +0 lines =@@
--
-+file.js(2,29): error TS2694: Namespace '"mod1"' has no exported member 'Dotted'.
-+
-+
-+==== file.js (1 errors) ====
-+ import { dummy } from './mod1'
-+ /** @type {import('./mod1').Dotted.Name} - should work */
-+ ~~~~~~
-+!!! error TS2694: Namespace '"mod1"' has no exported member 'Dotted'.
-+ var dot2
-+
-+==== mod1.js (0 errors) ====
-+ /** @typedef {number} Dotted.Name */
-+ export var dummy = 1
-+
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.js b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.js
index f4af80fe005..94d7aaee6e8 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.js
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.js
@@ -13,7 +13,9 @@ export var dummy = 1
//// [mod1.d.ts]
-export type Dotted = number;
+export declare namespace Dotted {
+ export type Name = number;
+}
/** @typedef {number} Dotted.Name */
export declare var dummy: number;
//// [file.d.ts]
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.types b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.types
index 29e2531a503..c56d0ae59bf 100644
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.types
+++ b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.types
@@ -6,7 +6,7 @@ import { dummy } from './mod1'
/** @type {import('./mod1').Dotted.Name} - should work */
var dot2
->dot2 : any
+>dot2 : number
=== mod1.js ===
/** @typedef {number} Dotted.Name */
diff --git a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.types.diff b/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.types.diff
deleted file mode 100644
index 9492ee05b70..00000000000
--- a/testdata/baselines/reference/submodule/conformance/jsDeclarationsImportNamespacedType.types.diff
+++ /dev/null
@@ -1,11 +0,0 @@
---- old.jsDeclarationsImportNamespacedType.types
-+++ new.jsDeclarationsImportNamespacedType.types
-@@= skipped -5, +5 lines =@@
-
- /** @type {import('./mod1').Dotted.Name} - should work */
- var dot2
-->dot2 : number
-+>dot2 : any
-
- === mod1.js ===
- /** @typedef {number} Dotted.Name */
\ No newline at end of file
diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/callbackTagNamespace.types.diff b/testdata/baselines/reference/submoduleAccepted/conformance/callbackTagNamespace.types.diff
deleted file mode 100644
index 44e0e024a3d..00000000000
--- a/testdata/baselines/reference/submoduleAccepted/conformance/callbackTagNamespace.types.diff
+++ /dev/null
@@ -1,15 +0,0 @@
---- old.callbackTagNamespace.types
-+++ new.callbackTagNamespace.types
-@@= skipped -12, +12 lines =@@
-
- /** @type {NS.Nested.Inner} */
- function f(space, peace) {
-->f : (space: Object, peace: Object) => string | number
-->space : Object
-->peace : Object
-+>f : (space: any, peace: any) => string
-+>space : any
-+>peace : any
-
- return '1'
- >'1' : "1"
\ No newline at end of file
diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportAliasExposedWithinNamespace.js.diff b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportAliasExposedWithinNamespace.js.diff
index 2beeb229f6a..7eac5d6a882 100644
--- a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportAliasExposedWithinNamespace.js.diff
+++ b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportAliasExposedWithinNamespace.js.diff
@@ -10,51 +10,59 @@
- /**
- * - Prop 1.
- */
-- prop1: myTypes.typeA;
++/**
++ * @namespace myTypes
++ * @global
++ * @type {Object}
++ */
++declare const myTypes: Record;
++export declare namespace myTypes {
++ export type typeA = string | RegExp | Array;
++}
++export declare namespace myTypes {
++ export type typeB = {
+ prop1: myTypes.typeA;
- /**
- * - Prop 2.
- */
-- prop2: string;
-- };
+ prop2: string;
+ };
- type typeC = myTypes.typeB | Function;
-}
- /**
- * @namespace myTypes
- * @global
- * @type {Object}
- */
--export const myTypes: {
-- [x: string]: any;
-+declare const myTypes: Record;
-+export type myTypes = string | RegExp | Array;
-+export type myTypes = {
-+ prop1: myTypes.typeA;
-+ prop2: string;
- };
-+export type myTypes = myTypes.typeB | Function;
++}
++export declare namespace myTypes {
++ export type typeC = myTypes.typeB | Function;
++}
+/** @typedef {string|RegExp|Array} myTypes.typeA */
-+/**
+ /**
+- * @namespace myTypes
+- * @global
+- * @type {Object}
+ * @typedef myTypes.typeB
+ * @property {myTypes.typeA} prop1 - Prop 1.
+ * @property {string} prop2 - Prop 2.
-+ */
+ */
+-export const myTypes: {
+- [x: string]: any;
+-};
+/** @typedef {myTypes.typeB|Function} myTypes.typeC */
+export { myTypes };
//// [file2.d.ts]
-export namespace testFnTypes {
- type input = boolean | myTypes.typeC;
--}
++import { myTypes } from './file.js';
+/**
+ * @namespace testFnTypes
+ * @global
+ * @type {Object}
+ */
+declare const testFnTypes: Record;
-+export type testFnTypes = boolean | myTypes.typeC;
++export declare namespace testFnTypes {
++ export type input = boolean | myTypes.typeC;
+ }
/** @typedef {boolean|myTypes.typeC} testFnTypes.input */
/**
- * @function testFn
-@@= skipped -33, +35 lines =@@
+@@= skipped -33, +44 lines =@@
* @param {testFnTypes.input} input - Input.
* @returns {number|null} Result.
*/
diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.js.diff b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.js.diff
index cbe87d68d42..f4c31866b75 100644
--- a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.js.diff
+++ b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportAliasExposedWithinNamespaceCjs.js.diff
@@ -6,42 +6,47 @@
*/
-export const myTypes: {
- [x: string]: any;
-+declare const myTypes: Record;
-+export type myTypes = string | RegExp | Array;
-+export type myTypes = {
-+ prop1: myTypes.typeA;
-+ prop2: string;
- };
+-};
-export namespace myTypes {
- type typeA = string | RegExp | Array;
- type typeB = {
- /**
- * - Prop 1.
- */
-- prop1: myTypes.typeA;
++declare const myTypes: Record;
++export declare namespace myTypes {
++ export type typeA = string | RegExp | Array;
++}
++export declare namespace myTypes {
++ export type typeB = {
+ prop1: myTypes.typeA;
- /**
- * - Prop 2.
- */
-- prop2: string;
-- };
+ prop2: string;
+ };
- type typeC = myTypes.typeB | Function;
-}
-+export type myTypes = myTypes.typeB | Function;
-+/** @typedef {string|RegExp|Array} myTypes.typeA */
++}
++export declare namespace myTypes {
++ export type typeC = myTypes.typeB | Function;
++}
++export { myTypes };
+ //// [file2.d.ts]
++import { myTypes } from './file.js';
+/**
-+ * @typedef myTypes.typeB
-+ * @property {myTypes.typeA} prop1 - Prop 1.
-+ * @property {string} prop2 - Prop 2.
++ * @namespace testFnTypes
++ * @global
++ * @type {Object}
+ */
-+/** @typedef {myTypes.typeB|Function} myTypes.typeC */
-+declare const _exported: Record;
-+export { _exported as myTypes };
- //// [file2.d.ts]
-+export type testFnTypes = boolean | myTypes.typeC;
++declare const testFnTypes: Record;
++export declare namespace testFnTypes {
++ export type input = boolean | myTypes.typeC;
++}
/** @typedef {boolean|myTypes.typeC} testFnTypes.input */
/**
* @function testFn
-@@= skipped -25, +25 lines =@@
+@@= skipped -25, +32 lines =@@
* @param {testFnTypes.input} input - Input.
* @returns {number|null} Result.
*/
diff --git a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportNamespacedType.js.diff b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportNamespacedType.js.diff
index fa52ab12a7f..504acd8f24a 100644
--- a/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportNamespacedType.js.diff
+++ b/testdata/baselines/reference/submoduleAccepted/conformance/jsDeclarationsImportNamespacedType.js.diff
@@ -4,12 +4,14 @@
//// [mod1.d.ts]
-+export type Dotted = number;
- /** @typedef {number} Dotted.Name */
+-/** @typedef {number} Dotted.Name */
-export const dummy: number;
-export namespace Dotted {
- type Name = number;
--}
++export declare namespace Dotted {
++ export type Name = number;
+ }
++/** @typedef {number} Dotted.Name */
+export declare var dummy: number;
//// [file.d.ts]
export {};
\ No newline at end of file
diff --git a/testdata/submoduleAccepted.txt b/testdata/submoduleAccepted.txt
index f091352ae0a..13e80ab503f 100644
--- a/testdata/submoduleAccepted.txt
+++ b/testdata/submoduleAccepted.txt
@@ -10,7 +10,6 @@ conformance/callbackOnConstructor.types.diff
conformance/callbackTag2.errors.txt.diff
conformance/callbackTag2.types.diff
conformance/callbackTag4.types.diff
-conformance/callbackTagNamespace.types.diff
conformance/callOfPropertylessConstructorFunction.errors.txt.diff
conformance/callOfPropertylessConstructorFunction.types.diff
conformance/callWithMissingVoidUndefinedUnknownAnyInJs(strict=false).errors.txt.diff
diff --git a/testdata/tests/cases/compiler/jsDocTypedefTagNamespace.ts b/testdata/tests/cases/compiler/jsDocTypedefTagNamespace.ts
new file mode 100644
index 00000000000..0ec801b58e2
--- /dev/null
+++ b/testdata/tests/cases/compiler/jsDocTypedefTagNamespace.ts
@@ -0,0 +1,40 @@
+// @checkJs: true
+// @allowJs: true
+// @strict: true
+// @outDir: ./out
+
+// @filename: a.js
+/** @typedef {number} NS.T */
+/** @typedef {string} NS.U */
+
+/** @type {NS.T} */
+const x = 1;
+
+/** @type {NS.U} */
+const y = "hello";
+
+// @filename: b.js
+/** @typedef {{age: number}} A.B.MyType */
+
+/** @type {A.B.MyType} */
+const z = { age: 42 };
+
+// @filename: c.js
+/** @callback NS.MyCallback
+ * @param {string} name
+ * @returns {void}
+ */
+
+/** @type {NS.MyCallback} */
+const f = (name) => {};
+
+// @filename: d.js
+/** @typedef {number} M.T */
+
+/** @type {M.T} */
+export const xd = 1;
+
+// @filename: e.js
+import { xd } from "./d.js";
+/** @type {import("./d.js").M.T} */
+export const ed = xd;