From 2a445a643f4af2542d87f349da200490226a7999 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 20 Aug 2026 20:02:42 +0000 Subject: [PATCH 1/2] Support import attributes on ambient modules --- .../src/api/node/protocol.generated.ts | 2 +- packages/typescript/src/ast/ast.generated.ts | 1 + .../typescript/src/ast/factory.generated.ts | 10 +- .../typescript/src/ast/visitor.generated.ts | 4 +- tools/scripts/tsc/ast.json | 5 + tsc/internal/api/encoder/decoder_generated.go | 5 +- tsc/internal/api/encoder/encoder_generated.go | 2 +- tsc/internal/ast/ast.go | 37 +- tsc/internal/ast/ast_generated.go | 23 +- tsc/internal/ast/utilities.go | 19 +- tsc/internal/binder/binder.go | 6 + tsc/internal/checker/checker.go | 324 +++++++++++++----- tsc/internal/checker/checker_test.go | 64 ++++ tsc/internal/checker/emitresolver.go | 7 - tsc/internal/checker/exports.go | 9 +- tsc/internal/checker/jsx.go | 2 +- tsc/internal/checker/nodebuilder_hover.go | 12 +- tsc/internal/checker/nodebuilderimpl.go | 3 + tsc/internal/checker/nodecopy.go | 2 +- tsc/internal/checker/symbolaccessibility.go | 2 +- tsc/internal/compiler/emitHost.go | 4 - tsc/internal/compiler/fileloader.go | 8 +- .../diagnostics/diagnostics_generated.go | 8 + .../diagnostics/extraDiagnosticMessages.json | 10 +- .../autoImportPatternAmbientModule_test.go | 43 +++ .../tests/quickInfoAmbientModule_test.go | 39 +++ tsc/internal/ls/autoimport/fix.go | 2 +- .../codeactions_fixmissingtypeannotation.go | 1 + tsc/internal/ls/hover.go | 17 + tsc/internal/ls/string_completions.go | 12 +- tsc/internal/parser/jsdoc.go | 1 + tsc/internal/parser/parser.go | 8 +- tsc/internal/parser/reparser.go | 2 +- tsc/internal/printer/emitresolver.go | 2 - tsc/internal/printer/printer.go | 6 + tsc/internal/testrunner/compiler_runner.go | 2 +- .../transformers/declarations/transform.go | 33 +- ...portAttributeArbitraryExtension.errors.txt | 17 + .../importAttributeArbitraryExtension.symbols | 27 ++ .../importAttributeArbitraryExtension.types | 30 ++ ...teDuplicatePatternMergedResolution.symbols | 107 ++++++ ...buteDuplicatePatternMergedResolution.types | 117 +++++++ .../importAttributeDynamicImports.symbols | 95 +++++ .../importAttributeDynamicImports.types | 120 +++++++ ...ortAttributeModuleAugmentations.errors.txt | 51 +++ ...importAttributeModuleAugmentations.symbols | 84 +++++ .../importAttributeModuleAugmentations.types | 91 +++++ .../importAttributeMostSpecificType.symbols | 70 ++++ .../importAttributeMostSpecificType.types | 72 ++++ ...tributePlainStringAmbientModule.errors.txt | 16 + ...tAttributePlainStringAmbientModule.symbols | 28 ++ ...ortAttributePlainStringAmbientModule.types | 29 ++ .../compiler/importAttributeType1.errors.txt | 55 +++ .../importAttributeTypeOnlyImports.symbols | 104 ++++++ .../importAttributeTypeOnlyImports.types | 102 ++++++ .../importAttributesDeclarationEmit.js | 41 +++ .../importAttributesDeclarationEmit.symbols | 57 +++ .../importAttributesDeclarationEmit.types | 55 +++ .../compiler/parseAssertEntriesError.types | 8 +- .../compiler/parseImportAttributesError.types | 8 +- ...tModuleAugmentationMergedSymbol.errors.txt | 32 ++ ...ientModuleAugmentationMergedSymbol.symbols | 63 ++++ ...mbientModuleAugmentationMergedSymbol.types | 65 ++++ ...ionModeOverrideWithOtherAttributes.symbols | 22 ++ ...utionModeOverrideWithOtherAttributes.types | 23 ++ .../importAssertion1(module=commonjs).js | 2 +- .../importAssertion1(module=commonjs).types | 26 +- .../importAssertion1(module=es2015).js | 2 +- .../importAssertion1(module=es2015).types | 26 +- .../importAssertion1(module=esnext).js | 2 +- .../importAssertion1(module=esnext).types | 26 +- .../importAssertion2(module=commonjs).js | 12 +- .../importAssertion2(module=es2015).js | 12 +- .../importAssertion2(module=esnext).js | 12 +- ...importAssertion3(module=es2015).errors.txt | 26 -- .../importAssertion3(module=es2015).js | 4 +- .../importAssertion3(module=es2015).types | 8 +- ...importAssertion3(module=esnext).errors.txt | 26 -- .../importAssertion3(module=esnext).js | 4 +- .../importAssertion3(module=esnext).types | 8 +- .../importAttributes1(module=commonjs).js | 2 +- .../importAttributes1(module=commonjs).types | 26 +- .../importAttributes1(module=es2015).js | 2 +- .../importAttributes1(module=es2015).types | 26 +- .../importAttributes1(module=esnext).js | 2 +- .../importAttributes1(module=esnext).types | 26 +- .../importAttributes2(module=commonjs).js | 12 +- .../importAttributes2(module=es2015).js | 12 +- .../importAttributes2(module=esnext).js | 12 +- ...mportAttributes3(module=es2015).errors.txt | 25 -- .../importAttributes3(module=es2015).js | 4 +- .../importAttributes3(module=es2015).types | 8 +- ...mportAttributes3(module=esnext).errors.txt | 25 -- .../importAttributes3(module=esnext).js | 4 +- .../importAttributes3(module=esnext).types | 8 +- .../conformance/importAttributes7.types | 10 +- .../conformance/importAttributes9.errors.txt | 4 +- .../conformance/importAttributes9.types | 6 +- .../conformance/importTag14.errors.txt | 8 +- .../importTag15(module=es2015).errors.txt | 18 - .../conformance/importTag15(module=es2015).js | 2 +- .../importTag15(module=esnext).errors.txt | 18 - .../conformance/importTag15(module=esnext).js | 2 +- ...dulesImportAssertions(module=node16).types | 8 +- ...dulesImportAssertions(module=node18).types | 8 +- ...dulesImportAssertions(module=node20).types | 8 +- ...lesImportAssertions(module=nodenext).types | 8 +- ...dulesImportAttributes(module=node16).types | 8 +- ...dulesImportAttributes(module=node18).types | 8 +- ...dulesImportAttributes(module=node20).types | 8 +- ...lesImportAttributes(module=nodenext).types | 8 +- ...rationEmitErrors(module=node16).errors.txt | 5 +- ...odeDeclarationEmitErrors(module=node16).js | 2 +- ...rationEmitErrors(module=node18).errors.txt | 5 +- ...odeDeclarationEmitErrors(module=node18).js | 2 +- ...rationEmitErrors(module=node20).errors.txt | 5 +- ...odeDeclarationEmitErrors(module=node20).js | 2 +- ...tionEmitErrors(module=nodenext).errors.txt | 5 +- ...eDeclarationEmitErrors(module=nodenext).js | 2 +- ...rationEmitErrors(module=node16).errors.txt | 28 +- ...rationEmitErrors(module=node18).errors.txt | 28 +- ...rationEmitErrors(module=node20).errors.txt | 28 +- ...tionEmitErrors(module=nodenext).errors.txt | 28 +- ...ationEmitErrors1(module=node16).errors.txt | 5 +- ...deDeclarationEmitErrors1(module=node16).js | 2 +- ...ationEmitErrors1(module=node18).errors.txt | 5 +- ...deDeclarationEmitErrors1(module=node18).js | 2 +- ...ationEmitErrors1(module=node20).errors.txt | 5 +- ...deDeclarationEmitErrors1(module=node20).js | 2 +- ...ionEmitErrors1(module=nodenext).errors.txt | 5 +- ...DeclarationEmitErrors1(module=nodenext).js | 2 +- .../nodeModulesJson(module=node16).errors.txt | 5 +- .../nodeModulesJson(module=node18).errors.txt | 5 +- .../nodeModulesJson(module=node20).errors.txt | 5 +- ...odeModulesJson(module=nodenext).errors.txt | 5 +- ...AmbientModuleWithImportAttributes.baseline | 171 +++++++++ ...AmbientModuleWithImportAttributes.baseline | 90 +++++ .../importAttributeArbitraryExtension.ts | 18 + ...tributeDuplicatePatternMergedResolution.ts | 47 +++ .../compiler/importAttributeDynamicImports.ts | 36 ++ .../importAttributeModuleAugmentations.ts | 45 +++ .../importAttributeMostSpecificType.ts | 31 ++ ...importAttributePlainStringAmbientModule.ts | 16 + .../cases/compiler/importAttributeType1.ts | 41 +++ .../importAttributeTypeOnlyImports.ts | 47 +++ .../importAttributesDeclarationEmit.ts | 32 ++ ...rnAmbientModuleAugmentationMergedSymbol.ts | 32 ++ ...solutionModeOverrideWithOtherAttributes.ts | 27 ++ 148 files changed, 2978 insertions(+), 691 deletions(-) create mode 100644 tsc/internal/fourslash/tests/autoImportPatternAmbientModule_test.go create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.types create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeDuplicatePatternMergedResolution.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeDuplicatePatternMergedResolution.types create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeDynamicImports.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeDynamicImports.types create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.types create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeMostSpecificType.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeMostSpecificType.types create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.types create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeType1.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeTypeOnlyImports.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeTypeOnlyImports.types create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.js create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.types create mode 100644 tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.types create mode 100644 tsc/testdata/baselines/reference/compiler/resolutionModeOverrideWithOtherAttributes.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/resolutionModeOverrideWithOtherAttributes.types delete mode 100644 tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).errors.txt delete mode 100644 tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).errors.txt delete mode 100644 tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).errors.txt delete mode 100644 tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).errors.txt delete mode 100644 tsc/testdata/baselines/reference/conformance/importTag15(module=es2015).errors.txt delete mode 100644 tsc/testdata/baselines/reference/conformance/importTag15(module=esnext).errors.txt create mode 100644 tsc/testdata/baselines/reference/fourslash/quickInfo/quickInfoMergedPatternAmbientModuleWithImportAttributes.baseline create mode 100644 tsc/testdata/baselines/reference/fourslash/quickInfo/quickInfoPatternAmbientModuleWithImportAttributes.baseline create mode 100644 tsc/testdata/tests/cases/compiler/importAttributeArbitraryExtension.ts create mode 100644 tsc/testdata/tests/cases/compiler/importAttributeDuplicatePatternMergedResolution.ts create mode 100644 tsc/testdata/tests/cases/compiler/importAttributeDynamicImports.ts create mode 100644 tsc/testdata/tests/cases/compiler/importAttributeModuleAugmentations.ts create mode 100644 tsc/testdata/tests/cases/compiler/importAttributeMostSpecificType.ts create mode 100644 tsc/testdata/tests/cases/compiler/importAttributePlainStringAmbientModule.ts create mode 100644 tsc/testdata/tests/cases/compiler/importAttributeType1.ts create mode 100644 tsc/testdata/tests/cases/compiler/importAttributeTypeOnlyImports.ts create mode 100644 tsc/testdata/tests/cases/compiler/importAttributesDeclarationEmit.ts create mode 100644 tsc/testdata/tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts create mode 100644 tsc/testdata/tests/cases/compiler/resolutionModeOverrideWithOtherAttributes.ts diff --git a/packages/typescript/src/api/node/protocol.generated.ts b/packages/typescript/src/api/node/protocol.generated.ts index 648eabeb2494b..3d8460a6f9031 100644 --- a/packages/typescript/src/api/node/protocol.generated.ts +++ b/packages/typescript/src/api/node/protocol.generated.ts @@ -162,7 +162,7 @@ export const childProperties: Readonly = { [SyntaxKind.ModuleDeclaration]: (data, cbNode, cbNodes) => visitNodes(cbNode, cbNodes, data.modifiers) || visitNode(cbNode, data.name) || + visitNode(cbNode, data.attributes) || visitNode(cbNode, data.body), [SyntaxKind.ImportEqualsDeclaration]: (data, cbNode, cbNodes) => visitNodes(cbNode, cbNodes, data.modifiers) || @@ -2955,11 +2956,12 @@ export function createJSDocNameReference(name: EntityName): JSDocNameReference { }) as unknown as JSDocNameReference; } -export function createModuleDeclaration(modifiers: readonly ModifierLike[] | undefined, keyword: SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword, name: ModuleName, body?: ModuleBody): ModuleDeclaration { +export function createModuleDeclaration(modifiers: readonly ModifierLike[] | undefined, keyword: SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword, name: ModuleName, attributes?: TypeLiteralNode, body?: ModuleBody): ModuleDeclaration { return new NodeObject(SyntaxKind.ModuleDeclaration, { modifiers: modifiers ? createNodeArray(modifiers) : undefined, keyword, name, + attributes, body, }) as unknown as ModuleDeclaration; } @@ -3726,8 +3728,8 @@ export function updateJSDocNameReference(node: JSDocNameReference, name: EntityN return node.name !== name ? createJSDocNameReference(name) : node; } -export function updateModuleDeclaration(node: ModuleDeclaration, modifiers: readonly ModifierLike[] | undefined, name: ModuleName, body?: ModuleBody): ModuleDeclaration { - return node.modifiers !== modifiers || node.name !== name || node.body !== body ? createModuleDeclaration(modifiers, node.keyword, name, body) : node; +export function updateModuleDeclaration(node: ModuleDeclaration, modifiers: readonly ModifierLike[] | undefined, name: ModuleName, attributes?: TypeLiteralNode, body?: ModuleBody): ModuleDeclaration { + return node.modifiers !== modifiers || node.name !== name || node.attributes !== attributes || node.body !== body ? createModuleDeclaration(modifiers, node.keyword, name, attributes, body) : node; } export function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, modifiers: readonly ModifierLike[] | undefined, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration { diff --git a/packages/typescript/src/ast/visitor.generated.ts b/packages/typescript/src/ast/visitor.generated.ts index 00625a299ae8a..7554a06a2eb3e 100644 --- a/packages/typescript/src/ast/visitor.generated.ts +++ b/packages/typescript/src/ast/visitor.generated.ts @@ -400,6 +400,7 @@ import { isTemplateHead, isTemplateLiteral, isTemplateMiddleOrTail, + isTypeLiteralNode, isTypeNode, isTypeParameterDeclaration, isTypePredicateParameterName, @@ -1342,8 +1343,9 @@ const visitEachChildTable: Record = { [SyntaxKind.ModuleDeclaration]: (node: ModuleDeclaration, visitor: Visitor): ModuleDeclaration => { const _modifiers = visitNodes(node.modifiers, visitor); const _name = visitNode(node.name, visitor, isModuleName); + const _attributes = visitNode(node.attributes, visitor, isTypeLiteralNode); const _body = visitNode(node.body, visitor, isModuleBody); - return updateModuleDeclaration(node, _modifiers, _name, _body); + return updateModuleDeclaration(node, _modifiers, _name, _attributes, _body); }, [SyntaxKind.ImportEqualsDeclaration]: (node: ImportEqualsDeclaration, visitor: Visitor): ImportEqualsDeclaration => { const _modifiers = visitNodes(node.modifiers, visitor); diff --git a/tools/scripts/tsc/ast.json b/tools/scripts/tsc/ast.json index 3c85511b463db..d15f18aa35b81 100644 --- a/tools/scripts/tsc/ast.json +++ b/tools/scripts/tsc/ast.json @@ -4807,6 +4807,11 @@ "type": "ModuleName", "private": true }, + { + "name": "Attributes", + "type": "TypeLiteralNode", + "optional": true + }, { "name": "Body", "inherited": true, diff --git a/tsc/internal/api/encoder/decoder_generated.go b/tsc/internal/api/encoder/decoder_generated.go index 6532a5a36ee05..ff5b23cc06f22 100644 --- a/tsc/internal/api/encoder/decoder_generated.go +++ b/tsc/internal/api/encoder/decoder_generated.go @@ -1062,8 +1062,9 @@ func (d *astDecoder) createChildrenNode(kind ast.Kind, data uint32, childIndices it := newChildIter(childIndices) modifiers := d.modifierListAt(it.nextIf(mask, 0)) name := d.nodeAt(it.nextIf(mask, 1)) - body := d.nodeAt(it.nextIf(mask, 2)) - return d.factory.NewModuleDeclaration(modifiers, keyword, name, body), nil + attributes := d.nodeAt(it.nextIf(mask, 2)) + body := d.nodeAt(it.nextIf(mask, 3)) + return d.factory.NewModuleDeclaration(modifiers, keyword, name, attributes, body), nil case ast.KindImportEqualsDeclaration: isTypeOnly := commonData&1 != 0 it := newChildIter(childIndices) diff --git a/tsc/internal/api/encoder/encoder_generated.go b/tsc/internal/api/encoder/encoder_generated.go index d3e7599e326c7..b4a9021b6cd0b 100644 --- a/tsc/internal/api/encoder/encoder_generated.go +++ b/tsc/internal/api/encoder/encoder_generated.go @@ -496,7 +496,7 @@ func getChildrenPropertyMask(node *ast.Node) uint8 { return (boolToByte(n.Name() != nil) << 0) case ast.KindModuleDeclaration: n := node.AsModuleDeclaration() - return (boolToByte(hasModifiers(n.Modifiers())) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.Body != nil) << 2) + return (boolToByte(hasModifiers(n.Modifiers())) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.Attributes != nil) << 2) | (boolToByte(n.Body != nil) << 3) case ast.KindImportEqualsDeclaration: n := node.AsImportEqualsDeclaration() return (boolToByte(hasModifiers(n.Modifiers())) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.ModuleReference != nil) << 2) diff --git a/tsc/internal/ast/ast.go b/tsc/internal/ast/ast.go index 07b0fdc62c644..a305269ca1f6b 100644 --- a/tsc/internal/ast/ast.go +++ b/tsc/internal/ast/ast.go @@ -9,6 +9,7 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/diagnostics" "github.com/microsoft/TypeScript/tsc/internal/spanmap" "github.com/microsoft/TypeScript/tsc/internal/tspath" "github.com/zeebo/xxh3" @@ -968,6 +969,8 @@ func (n *Node) Attributes() *Node { return n.AsJsxOpeningElement().Attributes case KindJsxSelfClosingElement: return n.AsJsxSelfClosingElement().Attributes + case KindModuleDeclaration: + return n.AsModuleDeclaration().Attributes } panic("Unhandled case in Node.Attributes: " + n.Kind.String()) } @@ -2211,44 +2214,28 @@ func (node *ExpressionWithTypeArguments) computeSubtreeFacts() SubtreeFacts { propagateEraseableSyntaxListSubtreeFacts(node.TypeArguments) } -func (node *ImportAttributesNode) GetResolutionModeOverride( /* !!! grammarErrorOnNode?: (node: Node, diagnostic: DiagnosticMessage) => void*/ ) (core.ResolutionMode, bool) { +func (node *ImportAttributesNode) GetResolutionModeOverride(grammarErrorOnNode func(node *Node, message *diagnostics.Message, args ...any) bool) (core.ResolutionMode, bool) { if node == nil { return core.ResolutionModeNone, false } attributes := node.AsImportAttributes().Attributes - if len(attributes.Nodes) != 1 { - // !!! - // grammarErrorOnNode?.( - // node, - // node.token === SyntaxKind.WithKeyword - // ? Diagnostics.Type_import_attributes_should_have_exactly_one_key_resolution_mode_with_value_import_or_require - // : Diagnostics.Type_import_assertions_should_have_exactly_one_key_resolution_mode_with_value_import_or_require, - // ); + attribute := core.Find(attributes.Nodes, func(attribute *Node) bool { + return attribute.Name().Text() == "resolution-mode" + }) + if attribute == nil { return core.ResolutionModeNone, false } - elem := attributes.Nodes[0].AsImportAttribute() - if !IsStringLiteralLike(elem.Name()) { - return core.ResolutionModeNone, false - } - if elem.Name().Text() != "resolution-mode" { - // !!! - // grammarErrorOnNode?.( - // elem.name, - // node.token === SyntaxKind.WithKeyword - // ? Diagnostics.resolution_mode_is_the_only_valid_key_for_type_import_attributes - // : Diagnostics.resolution_mode_is_the_only_valid_key_for_type_import_assertions, - // ); - return core.ResolutionModeNone, false - } + elem := attribute.AsImportAttribute() if !IsStringLiteralLike(elem.Value) { return core.ResolutionModeNone, false } if elem.Value.Text() != "import" && elem.Value.Text() != "require" { - // !!! - // grammarErrorOnNode?.(elem.value, Diagnostics.resolution_mode_should_be_either_require_or_import); + if grammarErrorOnNode != nil { + grammarErrorOnNode(elem.Value, diagnostics.X_resolution_mode_should_be_either_require_or_import) + } return core.ResolutionModeNone, false } if elem.Value.Text() == "import" { diff --git a/tsc/internal/ast/ast_generated.go b/tsc/internal/ast/ast_generated.go index 87c1e59f8653e..ea7b17ee4cb47 100644 --- a/tsc/internal/ast/ast_generated.go +++ b/tsc/internal/ast/ast_generated.go @@ -8039,36 +8039,41 @@ type ModuleDeclaration struct { LocalsContainerBase BodyBase CompositeBase - Keyword Kind - name *ModuleName + Keyword Kind + name *ModuleName + Attributes *TypeLiteralNodeNode // Optional } -func (f *NodeFactory) NewModuleDeclaration(modifiers *ModifierList, keyword Kind, name *ModuleName, body *ModuleBody) *Node { +func (f *NodeFactory) NewModuleDeclaration(modifiers *ModifierList, keyword Kind, name *ModuleName, attributes *TypeLiteralNodeNode, body *ModuleBody) *Node { data := &ModuleDeclaration{} data.modifiers = modifiers data.Keyword = keyword data.name = name + data.Attributes = attributes data.Body = body return f.newNode(KindModuleDeclaration, data) } -func (f *NodeFactory) UpdateModuleDeclaration(node *ModuleDeclaration, modifiers *ModifierList, keyword Kind, name *ModuleName, body *ModuleBody) *Node { - if modifiers != node.modifiers || keyword != node.Keyword || name != node.name || body != node.Body { - return updateNode(f.NewModuleDeclaration(modifiers, keyword, name, body), node.AsNode(), f.hooks) +func (f *NodeFactory) UpdateModuleDeclaration(node *ModuleDeclaration, modifiers *ModifierList, keyword Kind, name *ModuleName, attributes *TypeLiteralNodeNode, body *ModuleBody) *Node { + if modifiers != node.modifiers || keyword != node.Keyword || name != node.name || attributes != node.Attributes || body != node.Body { + return updateNode(f.NewModuleDeclaration(modifiers, keyword, name, attributes, body), node.AsNode(), f.hooks) } return node.AsNode() } func (node *ModuleDeclaration) ForEachChild(v Visitor) bool { - return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.Body) + return visitModifiers(v, node.modifiers) || + visit(v, node.name) || + visit(v, node.Attributes) || + visit(v, node.Body) } func (node *ModuleDeclaration) VisitEachChild(v *NodeVisitor) *Node { - return v.Factory.UpdateModuleDeclaration(node, v.visitModifiers(node.modifiers), node.Keyword, v.visitNode(node.name), v.visitNode(node.Body)) + return v.Factory.UpdateModuleDeclaration(node, v.visitModifiers(node.modifiers), node.Keyword, v.visitNode(node.name), v.visitNode(node.Attributes), v.visitNode(node.Body)) } func (node *ModuleDeclaration) Clone(f NodeFactoryCoercible) *Node { - return cloneNode(f.AsNodeFactory().NewModuleDeclaration(node.Modifiers(), node.Keyword, node.name, node.Body), node.AsNode(), f.AsNodeFactory().hooks) + return cloneNode(f.AsNodeFactory().NewModuleDeclaration(node.Modifiers(), node.Keyword, node.name, node.Attributes, node.Body), node.AsNode(), f.AsNodeFactory().hooks) } func (node *ModuleDeclaration) Name() *DeclarationName { diff --git a/tsc/internal/ast/utilities.go b/tsc/internal/ast/utilities.go index 42058ea2c399f..b432c64c99421 100644 --- a/tsc/internal/ast/utilities.go +++ b/tsc/internal/ast/utilities.go @@ -1941,14 +1941,24 @@ func GetExternalModuleName(node *Node) *Expression { panic("Unhandled case in getExternalModuleName") } +func HasImportAttributes(node *Node) bool { + switch node.Kind { + case KindImportDeclaration, KindJSImportDeclaration, KindExportDeclaration, KindImportType: + return true + } + return false +} + func GetImportAttributes(node *Node) *Node { switch node.Kind { case KindImportDeclaration, KindJSImportDeclaration: return node.AsImportDeclaration().Attributes case KindExportDeclaration: return node.AsExportDeclaration().Attributes + case KindImportType: + return node.AsImportTypeNode().Attributes } - panic("Unhandled case in getImportAttributes") + panic("Unhandled case in getImportAttributes: " + node.Kind.String()) } func getImportTypeNodeLiteral(node *Node) *Node { @@ -3198,10 +3208,6 @@ func IsPartOfTypeOnlyImportOrExportDeclaration(node *Node) bool { return FindAncestor(node, IsTypeOnlyImportOrExportDeclaration) != nil } -func IsPartOfExclusivelyTypeOnlyImportOrExportDeclaration(node *Node) bool { - return FindAncestor(node, IsExclusivelyTypeOnlyImportOrExport) != nil -} - func IsEmittableImport(node *Node) bool { switch node.Kind { case KindImportDeclaration: @@ -3239,7 +3245,7 @@ func HasResolutionModeOverride(node *Node) bool { attributes = node.AsExportDeclaration().Attributes } if attributes != nil { - _, ok := attributes.GetResolutionModeOverride() + _, ok := attributes.GetResolutionModeOverride(nil) return ok } return false @@ -3521,6 +3527,7 @@ func ReplaceModifiers(factory *NodeFactory, node *Node, modifierArray *ModifierL modifierArray, node.AsModuleDeclaration().Keyword, node.Name(), + node.Attributes(), node.Body(), ) case KindImportEqualsDeclaration: diff --git a/tsc/internal/binder/binder.go b/tsc/internal/binder/binder.go index 38769558c01d4..4445a0d515e17 100644 --- a/tsc/internal/binder/binder.go +++ b/tsc/internal/binder/binder.go @@ -309,6 +309,9 @@ func (b *Binder) getDeclarationName(node *ast.Node) string { if ast.IsGlobalScopeAugmentation(node) { return ast.InternalSymbolNameGlobal } + if pattern := core.TryParsePattern(moduleName); pattern.IsValid() && pattern.StarIndex >= 0 { + return "\"" + moduleName + "\"" + ast.InternalSymbolNamePrefix + "pattern@" + strconv.FormatUint(uint64(ast.GetNodeId(node)), 10) + } return "\"" + moduleName + "\"" } if ast.IsPrivateIdentifier(name) { @@ -781,12 +784,15 @@ func (b *Binder) bindModuleDeclaration(node *ast.Node) { symbol := b.declareSymbolAndAddToSymbolTable(node, ast.SymbolFlagsValueModule, ast.SymbolFlagsValueModuleExcludes) if ast.IsStringLiteral(name) { + attributes := node.AsModuleDeclaration().Attributes pattern := core.TryParsePattern(name.Text()) if !pattern.IsValid() { // An invalid pattern - must have multiple wildcards. b.errorOnFirstToken(name, diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, name.Text()) } else if pattern.StarIndex >= 0 { b.file.PatternAmbientModules = append(b.file.PatternAmbientModules, &ast.PatternAmbientModule{Pattern: pattern, Symbol: symbol}) + } else if attributes != nil { + b.errorOnNode(name, diagnostics.An_ambient_module_declaration_with_import_attributes_must_use_a_pattern_name_with_an_Asterisk_character) } } } diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 2a4ead5003a89..1b46a1b34c453 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -770,6 +770,8 @@ type Checker struct { anyBaseTypeIndexInfo *IndexInfo patternAmbientModules []*ast.PatternAmbientModule patternAmbientModuleAugmentations ast.SymbolTable + patternAmbientModuleAugmentationTargets ast.SymbolTable + moduleImportAttributesTypes map[*ast.Symbol]*Type globalObjectType *Type globalFunctionType *Type globalCallableFunctionType *Type @@ -1065,6 +1067,7 @@ func NewChecker(program Program, tracer *Tracer) (*Checker, *sync.Mutex) { c.comparableRelation = &Relation{} c.identityRelation = &Relation{} c.enumRelation = make(map[EnumRelationKey]RelationComparisonResult) + c.moduleImportAttributesTypes = make(map[*ast.Symbol]*Type) c.getGlobalESSymbolType = c.getGlobalTypeResolver("Symbol", 0 /*arity*/, false /*reportErrors*/) c.getGlobalBigIntType = c.getGlobalTypeResolver("BigInt", 0 /*arity*/, false /*reportErrors*/) c.getGlobalImportMetaType = c.getGlobalTypeResolver("ImportMeta", 0 /*arity*/, true /*reportErrors*/) @@ -1378,6 +1381,7 @@ func (c *Checker) initializeChecker() { for _, symbol := range ambientModuleSymbols { c.mergeGlobalSymbol(symbol) } + c.mergePatternAmbientModules() // merge _nonglobal_ module augmentations. // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed for _, list := range augmentations { @@ -1400,6 +1404,33 @@ func (c *Checker) mergeGlobalSymbol(symbol *ast.Symbol) { c.globals[symbol.Name] = merged } +// Pattern ambient modules are merged together if they have the same pattern and identical import attributes type. +func (c *Checker) mergePatternAmbientModules() { + groupsByPattern := make(map[string][]int) + grouped := make([]*ast.PatternAmbientModule, 0, len(c.patternAmbientModules)) + for _, module := range c.patternAmbientModules { + attributesType := c.getTypeOfModuleImportAttributes(module.Symbol) + groupIndex := -1 + for _, index := range groupsByPattern[module.Pattern.Text] { + if c.isTypeIdenticalTo(attributesType, c.getTypeOfModuleImportAttributes(grouped[index].Symbol)) { + groupIndex = index + break + } + } + if groupIndex == -1 { + groupsByPattern[module.Pattern.Text] = append(groupsByPattern[module.Pattern.Text], len(grouped)) + grouped = append(grouped, &ast.PatternAmbientModule{Pattern: module.Pattern, Symbol: module.Symbol}) + } else { + grouped[groupIndex].Symbol = c.mergeSymbol(grouped[groupIndex].Symbol, module.Symbol, false /*unidirectional*/) + } + } + for _, module := range c.patternAmbientModules { + if _, ok := c.globals[module.Symbol.Name]; ok { + c.globals[module.Symbol.Name] = c.getMergedSymbol(module.Symbol) + } + } +} + func (c *Checker) mergeModuleAugmentation(moduleName *ast.Node) { moduleNode := moduleName.Parent moduleAugmentation := moduleNode.AsModuleDeclaration() @@ -1418,7 +1449,8 @@ func (c *Checker) mergeModuleAugmentation(moduleName *ast.Node) { if moduleName.Parent.Parent.Flags&ast.NodeFlagsAmbient == 0 { moduleNotFoundError = diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found } - mainModule := c.resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError /*ignoreErrors*/, false /*isForAugmentation*/, true) + // We ban import attributes on module augmentation declarations. + mainModule := c.resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, false /*ignoreErrors*/, true /*isForAugmentation*/, nil /*importAttributesType*/) if mainModule == nil { return } @@ -1431,11 +1463,12 @@ func (c *Checker) mergeModuleAugmentation(moduleName *ast.Node) { // all the exports both from the pattern and from the augmentation, but // 'getMergedSymbol()' on *.foo only gives you exports from *.foo. if core.Some(c.patternAmbientModules, func(module *ast.PatternAmbientModule) bool { - return mainModule == module.Symbol + return mainModule == c.getMergedSymbol(module.Symbol) }) { merged := c.mergeSymbol(moduleAugmentation.Symbol, mainModule, true /*unidirectional*/) // moduleName will be a StringLiteral since this is not `declare global`. ast.GetSymbolTable(&c.patternAmbientModuleAugmentations)[moduleName.Text()] = merged + ast.GetSymbolTable(&c.patternAmbientModuleAugmentationTargets)[moduleName.Text()] = mainModule } else { if mainModule.Exports[ast.InternalSymbolNameExportStar] != nil && len(moduleAugmentation.Symbol.Exports) != 0 { // We may need to merge the module augmentation's exports into the target symbols of the resolved exports @@ -3335,39 +3368,16 @@ func (c *Checker) checkImportType(node *ast.Node) { c.getResolutionModeOverride(attributes.AsImportAttributes(), true /*reportErrors*/) } c.checkTypeReferenceOrImport(node) + c.checkImportAttributes(node) } func (c *Checker) getResolutionModeOverride(node *ast.ImportAttributes, reportErrors bool) core.ResolutionMode { - if len(node.Attributes.Nodes) != 1 { - if reportErrors { - c.grammarErrorOnNode(node.AsNode(), diagnostics.Type_import_attributes_should_have_exactly_one_key_resolution_mode_with_value_import_or_require) - } - return core.ResolutionModeNone - } - elem := node.Attributes.Nodes[0] - if !ast.IsStringLiteralLike(elem.Name()) { - return core.ResolutionModeNone - } - if elem.Name().Text() != "resolution-mode" { - if reportErrors { - c.grammarErrorOnNode(elem.Name(), diagnostics.X_resolution_mode_is_the_only_valid_key_for_type_import_attributes) - } - return core.ResolutionModeNone - } - value := elem.AsImportAttribute().Value - if !ast.IsStringLiteralLike(value) { - return core.ResolutionModeNone - } - if value.Text() != "import" && value.Text() != "require" { - if reportErrors { - c.grammarErrorOnNode(value, diagnostics.X_resolution_mode_should_be_either_require_or_import) - } - return core.ResolutionModeNone - } - if value.Text() == "import" { - return core.ResolutionModeESM + var grammarErrorOnNode func(node *ast.Node, message *diagnostics.Message, args ...any) bool + if reportErrors { + grammarErrorOnNode = c.grammarErrorOnNode } - return core.ResolutionModeCommonJS + mode, _ := node.GetResolutionModeOverride(grammarErrorOnNode) + return mode } func (c *Checker) checkNamedTupleMember(node *ast.Node) { @@ -5217,6 +5227,10 @@ func (c *Checker) checkModuleDeclaration(node *ast.Node) { if isGlobalAugmentation && !inAmbientContext { c.error(node.Name(), diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context) } + attributes := node.AsModuleDeclaration().Attributes + if attributes != nil { + c.checkSourceElement(attributes) + } isAmbientExternalModule := ast.IsAmbientModule(node) contextErrorMessage := core.IfElse(isAmbientExternalModule, diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file, @@ -5266,6 +5280,9 @@ func (c *Checker) checkModuleDeclaration(node *ast.Node) { } if isAmbientExternalModule { if ast.IsExternalModuleAugmentation(node) { + if attributes != nil { + c.error(attributes, diagnostics.Import_attributes_are_not_allowed_on_a_module_augmentation) + } // body of the augmentation should be checked for consistency only if augmentation was applied to its target (either global scope or module) // otherwise we'll be swamped in cascading errors. // We can detect if augmentation was applied using following rules: @@ -5292,7 +5309,37 @@ func (c *Checker) checkModuleDeclaration(node *ast.Node) { c.error(node.Name(), diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces) } } + if attributes != nil { + importAttributesType := c.getGlobalImportAttributesTypeChecked() + moduleAttributesType := c.getTypeOfModuleDeclarationImportAttributes(node) + if importAttributesType != c.emptyObjectType { + c.checkTypeAssignableTo(moduleAttributesType, importAttributesType, attributes, nil) + } + } + } +} + +func (c *Checker) getTypeOfModuleDeclarationImportAttributes(moduleDeclaration *ast.Node) *Type { + attributes := moduleDeclaration.AsModuleDeclaration().Attributes + if attributes == nil { + return c.emptyObjectType } + return c.getTypeFromTypeNode(attributes) +} + +func (c *Checker) getTypeOfModuleImportAttributes(symbol *ast.Symbol) *Type { + if t, ok := c.moduleImportAttributesTypes[symbol]; ok { + return t + } + var result *Type + moduleDecl := core.Find(symbol.Declarations, ast.IsModuleWithStringLiteralName) + if moduleDecl == nil { + result = c.emptyObjectType + } else { + result = c.getTypeOfModuleDeclarationImportAttributes(moduleDecl) + } + c.moduleImportAttributesTypes[symbol] = result + return result } func isInstantiatedModule(node *ast.Node, preserveConstEnums bool) bool { @@ -5358,6 +5405,7 @@ func (c *Checker) checkImportDeclaration(node *ast.ImportDeclarationNode) { c.grammarErrorOnFirstToken(node, diagnostics.An_import_declaration_cannot_have_modifiers) } if c.checkExternalImportOrExportDeclaration(node) { + attributes := ast.GetImportAttributes(node) var resolvedModule *ast.Symbol importClause := node.ImportClause() moduleSpecifier := node.ModuleSpecifier() @@ -5376,7 +5424,7 @@ func (c *Checker) checkImportDeclaration(node *ast.ImportDeclarationNode) { c.checkExternalEmitHelpers(node, ExternalEmitHelpersImportStar) } } else { - resolvedModule = c.resolveExternalModuleName(node, node.ModuleSpecifier(), false) + resolvedModule = c.resolveExternalModuleName(node, node.ModuleSpecifier(), false, c.getTypeFromImportAttributes(attributes)) if resolvedModule != nil { for _, binding := range namedBindings.Elements() { c.checkImportBinding(binding) @@ -5393,7 +5441,7 @@ func (c *Checker) checkImportDeclaration(node *ast.ImportDeclarationNode) { if !importClause.IsTypeOnly() && core.ModuleKindNode18 <= c.moduleKind && c.moduleKind <= core.ModuleKindNodeNext && - c.isOnlyImportableAsDefault(moduleSpecifier, resolvedModule) && + c.isOnlyImportableAsDefault(moduleSpecifier, resolvedModule, c.getTypeFromImportAttributes(attributes)) && !hasTypeJsonImportAttribute(node) { c.error(moduleSpecifier, diagnostics.Importing_a_JSON_file_into_an_ECMAScript_module_requires_a_type_Colon_json_import_attribute_when_module_is_set_to_0, c.moduleKind.String()) } @@ -5403,7 +5451,7 @@ func (c *Checker) checkImportDeclaration(node *ast.ImportDeclarationNode) { if !ignoreErrors { errorMessage = diagnostics.Cannot_find_module_or_type_declarations_for_side_effect_import_of_0 } - c.resolveExternalModuleNameWorker(node, moduleSpecifier, errorMessage, ignoreErrors, false /*isForAugmentation*/) + c.resolveExternalModuleNameWorker(node, moduleSpecifier, errorMessage, ignoreErrors, false /*isForAugmentation*/, c.getTypeFromImportAttributes(attributes)) } } c.checkImportAttributes(node) @@ -5493,10 +5541,10 @@ func (c *Checker) checkImportAttributes(declaration *ast.Node) { if importAttributesType != c.emptyObjectType { c.checkTypeAssignableTo(c.getTypeFromImportAttributes(node), c.getNullableType(importAttributesType, TypeFlagsUndefined), node, nil) } - isTypeOnly := ast.IsExclusivelyTypeOnlyImportOrExport(declaration) + isTypeOnly := ast.IsExclusivelyTypeOnlyImportOrExport(declaration) || ast.IsImportTypeNode(declaration) override := c.getResolutionModeOverride(node.AsImportAttributes(), isTypeOnly) - if isTypeOnly && override != core.ResolutionModeNone { - return // Other grammar checks do not apply to type-only imports with resolution mode attributes + if isTypeOnly { + return // Other grammar checks do not apply to type-only imports with import attributes } if !c.moduleKind.SupportsImportAttributes() { @@ -5504,30 +5552,36 @@ func (c *Checker) checkImportAttributes(declaration *ast.Node) { return } - if moduleSpecifier := getModuleSpecifierFromNode(declaration); moduleSpecifier != nil { + if moduleSpecifier := ast.GetExternalModuleName(declaration); moduleSpecifier != nil { if c.getEmitSyntaxForModuleSpecifierExpression(moduleSpecifier) == core.ModuleKindCommonJS { c.grammarErrorOnNode(node, diagnostics.Import_attributes_are_not_allowed_on_statements_that_compile_to_CommonJS_require_calls) return } } - if isTypeOnly { - c.grammarErrorOnNode(node, diagnostics.Import_attributes_cannot_be_used_with_type_only_imports_or_exports) - return - } if override != core.ResolutionModeNone { c.grammarErrorOnNode(node, diagnostics.X_resolution_mode_can_only_be_set_for_type_only_imports) } } func (c *Checker) getTypeFromImportAttributes(node *ast.Node) *Type { + if node == nil { + return nil + } + if ast.IsImportAttributes(node) { + return c.checkImportAttributesExpression(node) + } + return c.checkExpressionCached(node) +} + +func (c *Checker) checkImportAttributesExpression(node *ast.Node) *Type { links := c.typeNodeLinks.Get(node) if links.resolvedType == nil { symbol := c.newSymbol(ast.SymbolFlagsObjectLiteral, ast.InternalSymbolNameImportAttributes) members := make(ast.SymbolTable) - for _, attr := range node.AsImportAttributes().Attributes.Nodes { - member := c.newSymbol(ast.SymbolFlagsProperty, attr.Name().Text()) - c.valueSymbolLinks.Get(member).resolvedType = c.getRegularTypeOfLiteralType(c.checkExpression(attr.AsImportAttribute().Value)) + for _, attribute := range node.AsImportAttributes().Attributes.Nodes { + member := c.newSymbol(ast.SymbolFlagsProperty, attribute.Name().Text()) + c.valueSymbolLinks.Get(member).resolvedType = c.getRegularTypeOfLiteralType(c.checkExpressionCached(attribute.AsImportAttribute().Value)) members[member.Name] = member } t := c.newAnonymousType(symbol, members, nil, nil, nil) @@ -5537,6 +5591,20 @@ func (c *Checker) getTypeFromImportAttributes(node *ast.Node) *Type { return links.resolvedType } +func (c *Checker) getImportAttributesTypeForModuleSpecifier(moduleSpecifier *ast.Node) *Type { + parent := moduleSpecifier.Parent + switch { + case ast.IsImportDeclarationOrJSImportDeclaration(parent) || ast.IsExportDeclaration(parent): + return c.getTypeFromImportAttributes(ast.GetImportAttributes(parent)) + case ast.IsLiteralTypeNode(parent) && ast.IsLiteralImportTypeNode(parent.Parent): + return c.getTypeFromImportAttributes(ast.GetImportAttributes(parent.Parent)) + case ast.IsImportCall(parent) && len(parent.Arguments()) > 1: + options := parent.Arguments()[1] + return c.getTypeOfPropertyOfType(c.checkExpressionCached(options), "with") + } + return nil +} + func (c *Checker) checkImportEqualsDeclaration(node *ast.Node) { diagnostic := core.IfElse(ast.IsInJSFile(node), diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module, @@ -5608,7 +5676,7 @@ func (c *Checker) checkExportDeclaration(node *ast.ExportDeclarationNode) { } else { // export * from "foo" // export * as ns from "foo"; - moduleSymbol := c.resolveExternalModuleName(node, exportDecl.ModuleSpecifier, false) + moduleSymbol := c.resolveExternalModuleName(node, exportDecl.ModuleSpecifier, false, c.getTypeFromImportAttributes(ast.GetImportAttributes(node))) if moduleSymbol != nil && hasExportAssignmentSymbol(moduleSymbol) { c.error(exportDecl.ModuleSpecifier, diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, c.symbolToString(moduleSymbol)) } else if exportDecl.ExportClause != nil { @@ -5634,7 +5702,12 @@ func (c *Checker) checkExternalModuleNameInGlobalScope(node *ast.Node) { return } if moduleName := ast.GetExternalModuleName(node); moduleName != nil { - c.resolveExternalModuleName(node, moduleName, false) + var attributes *ast.ImportAttributesNode + if ast.HasImportAttributes(node) { + attributes = ast.GetImportAttributes(node) + } + importAttributesType := c.getTypeFromImportAttributes(attributes) + c.resolveExternalModuleName(node, moduleName, false, importAttributesType) } } @@ -8375,6 +8448,7 @@ func (c *Checker) checkImportCallExpression(node *ast.Node) *Type { if specifierType.flags&TypeFlagsNullable != 0 || !c.isTypeAssignableTo(specifierType, c.stringType) { c.error(specifier, diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, c.TypeToString(specifierType)) } + var importAttributesType *Type if optionsType != nil { importCallOptionsType := c.getGlobalImportCallOptionsTypeChecked() if importCallOptionsType != c.emptyObjectType { @@ -8388,13 +8462,14 @@ func (c *Checker) checkImportCallExpression(node *ast.Node) *Type { } } } + importAttributesType = c.getTypeOfPropertyOfType(optionsType, "with") } // resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal - moduleSymbol := c.resolveExternalModuleName(node, specifier, false /*ignoreErrors*/) + moduleSymbol := c.resolveExternalModuleName(node, specifier, false /*ignoreErrors*/, importAttributesType) if moduleSymbol != nil { esModuleSymbol := c.resolveExternalModuleSymbol(moduleSymbol, true /*dontResolveAlias*/) if esModuleSymbol != nil { - syntheticType := c.getTypeWithSyntheticDefaultOnly(c.getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier) + syntheticType := c.getTypeWithSyntheticDefaultOnly(c.getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier, importAttributesType) if syntheticType == nil { syntheticType = c.getTypeWithSyntheticDefaultImportType(c.getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier) } @@ -13716,11 +13791,28 @@ func (c *Checker) hasDefaultValue(node *ast.Node) bool { func (c *Checker) isConstContext(node *ast.Node) bool { parent := node.Parent return ast.IsConstAssertion(parent) || + c.isInlineImportAttributes(node) || c.isValidConstAssertionArgument(node) && c.isConstTypeVariable(c.getContextualType(node, ContextFlagsNone), 0) || (ast.IsParenthesizedExpression(parent) || ast.IsArrayLiteralExpression(parent) || ast.IsSpreadElement(parent)) && c.isConstContext(parent) || (ast.IsPropertyAssignment(parent) || ast.IsShorthandPropertyAssignment(parent) || ast.IsTemplateSpan(parent)) && c.isConstContext(parent.Parent) } +func (c *Checker) isInlineImportAttributes(node *ast.Node) bool { + if !ast.IsObjectLiteralExpression(node) || !ast.IsPropertyAssignment(node.Parent) || node.Parent.Initializer() != node { + return false + } + property := node.Parent + if (!ast.IsIdentifier(property.Name()) && !ast.IsStringLiteralLike(property.Name())) || property.Name().Text() != "with" { + return false + } + options := property.Parent + if !ast.IsObjectLiteralExpression(options) { + return false + } + importCall := ast.FindAncestor(options, ast.IsImportCall) + return importCall != nil && len(importCall.Arguments()) > 1 && ast.SkipParentheses(importCall.Arguments()[1]) == options +} + func (c *Checker) isValidConstAssertionArgument(node *ast.Node) bool { switch node.Kind { case ast.KindStringLiteral, ast.KindNoSubstitutionTemplateLiteral, ast.KindNumericLiteral, ast.KindBigIntLiteral, ast.KindTrueKeyword, @@ -14537,7 +14629,7 @@ func (c *Checker) getTargetOfImportEqualsDeclaration(node *ast.Node) *ast.Symbol if moduleReference == nil { moduleReference = ast.GetExternalModuleImportEqualsDeclarationExpression(node) } - immediate := c.resolveExternalModuleName(node, moduleReference, false /*ignoreErrors*/) + immediate := c.resolveExternalModuleName(node, moduleReference, false /*ignoreErrors*/, nil /*importAttributesType*/) resolved := c.resolveExternalModuleSymbol(immediate, true /*dontResolveAlias*/) if resolved != nil && core.ModuleKindNode20 <= c.moduleKind && c.moduleKind <= core.ModuleKindNodeNext { moduleExports := c.getExportOfModule(resolved, ast.InternalSymbolNameModuleExports, node, true /*dontResolveAlias*/) @@ -14554,7 +14646,7 @@ func (c *Checker) getTargetOfImportEqualsDeclaration(node *ast.Node) *ast.Symbol } func (c *Checker) resolveExternalModuleTypeByLiteral(name *ast.Node) *Type { - moduleSym := c.resolveExternalModuleName(name, name, false /*ignoreErrors*/) + moduleSym := c.resolveExternalModuleName(name, name, false /*ignoreErrors*/, nil /*importAttributesType*/) if moduleSym != nil { resolvedModuleSymbol := c.resolveExternalModuleSymbol(moduleSym, false /*dontResolveAlias*/) if resolvedModuleSymbol != nil { @@ -14620,7 +14712,7 @@ func (c *Checker) getTypeOnlyDeclarationOfEntityName(name *ast.Node) *ast.Node { } func (c *Checker) getTargetOfImportClause(node *ast.Node) *ast.Symbol { - moduleSymbol := c.resolveExternalModuleName(node, getModuleSpecifierFromNode(node.Parent), false /*ignoreErrors*/) + moduleSymbol := c.resolveExternalModuleName(node, getModuleSpecifierFromNode(node.Parent), false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(node.Parent))) if moduleSymbol != nil { return c.getTargetOfModuleDefault(moduleSymbol, node, true /*dontResolveAlias*/) } @@ -14655,7 +14747,16 @@ func (c *Checker) getTargetOfModuleDefault(moduleSymbol *ast.Symbol, node *ast.N if specifier == nil { return exportDefaultSymbol } - hasDefaultOnly := c.isOnlyImportableAsDefault(specifier, moduleSymbol) + // node is ImportClause | ImportSpecifier | ExportSpecifier + var attributes *ast.ImportAttributesNode + if ast.IsImportClause(node) { + attributes = ast.GetImportAttributes(node.Parent) + } else if ast.IsImportSpecifier(node) { + attributes = ast.GetImportAttributes(node.Parent.Parent.Parent) + } else if ast.IsExportSpecifier(node) { + attributes = ast.GetImportAttributes(node.Parent.Parent) + } + hasDefaultOnly := c.isOnlyImportableAsDefault(specifier, moduleSymbol, c.getTypeFromImportAttributes(attributes)) hasSyntheticDefault := c.canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, specifier) if exportDefaultSymbol == nil && !hasSyntheticDefault && !hasDefaultOnly { if ast.IsImportClause(node) { @@ -14696,7 +14797,7 @@ func (c *Checker) reportNonDefaultExport(moduleSymbol *ast.Symbol, node *ast.Nod if !(ast.IsExportDeclaration(decl) && decl.ModuleSpecifier() != nil) { return false } - resolvedExternalModuleName := c.resolveExternalModuleName(decl, decl.ModuleSpecifier(), false /*ignoreErrors*/) + resolvedExternalModuleName := c.resolveExternalModuleName(decl, decl.ModuleSpecifier(), false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(decl))) return resolvedExternalModuleName != nil && resolvedExternalModuleName.Exports[ast.InternalSymbolNameDefault] != nil }) if defaultExport != nil { @@ -14721,7 +14822,7 @@ func (c *Checker) resolveExportByName(moduleSymbol *ast.Symbol, name string, sou func (c *Checker) getTargetOfNamespaceImport(node *ast.Node) *ast.Symbol { moduleSpecifier := c.getModuleSpecifierForImportOrExport(node) - immediate := c.resolveExternalModuleName(node, moduleSpecifier, false /*ignoreErrors*/) + immediate := c.resolveExternalModuleName(node, moduleSpecifier, false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(node.Parent.Parent))) resolved := c.resolveESModuleSymbol(immediate, node, moduleSpecifier) c.markSymbolOfAliasDeclarationIfTypeOnly(node, nil) return resolved @@ -14730,7 +14831,7 @@ func (c *Checker) getTargetOfNamespaceImport(node *ast.Node) *ast.Symbol { func (c *Checker) getTargetOfNamespaceExport(node *ast.Node) *ast.Symbol { moduleSpecifier := c.getModuleSpecifierForImportOrExport(node) if moduleSpecifier != nil { - immediate := c.resolveExternalModuleName(node, moduleSpecifier, false /*ignoreErrors*/) + immediate := c.resolveExternalModuleName(node, moduleSpecifier, false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(node.Parent))) resolved := c.resolveESModuleSymbol(immediate, node, moduleSpecifier) c.markSymbolOfAliasDeclarationIfTypeOnly(node, nil) return resolved @@ -14743,7 +14844,7 @@ func (c *Checker) getTargetOfImportSpecifier(node *ast.Node) *ast.Symbol { if ast.IsImportSpecifier(node) && ast.ModuleExportNameIsDefault(name) { specifier := c.getModuleSpecifierForImportOrExport(node) if specifier != nil { - moduleSymbol := c.resolveExternalModuleName(node, specifier, false /*ignoreErrors*/) + moduleSymbol := c.resolveExternalModuleName(node, specifier, false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(node.Parent.Parent.Parent))) if moduleSymbol != nil { return c.getTargetOfModuleDefault(moduleSymbol, node, true /*dontResolveAlias*/) } @@ -14765,7 +14866,12 @@ func (c *Checker) getExternalModuleMember(node *ast.Node, specifier *ast.Node, d if moduleSpecifier == nil { moduleSpecifier = ast.GetExternalModuleName(node) } - moduleSymbol := c.resolveExternalModuleName(node, moduleSpecifier, false /*ignoreErrors*/) + var attributes *ast.ImportAttributesNode + if ast.HasImportAttributes(node) { + attributes = ast.GetImportAttributes(node) + } + importAttributesType := c.getTypeFromImportAttributes(attributes) + moduleSymbol := c.resolveExternalModuleName(node, moduleSpecifier, false /*ignoreErrors*/, importAttributesType) var name *ast.Node if !ast.IsPropertyAccessExpression(specifier) { name = specifier.PropertyNameOrName() @@ -14804,7 +14910,7 @@ func (c *Checker) getExternalModuleMember(node *ast.Node, specifier *ast.Node, d symbolFromModule := c.getExportOfModule(exportContainer, nameText, specifier, dontResolveAlias) if symbolFromModule == nil && nameText == ast.InternalSymbolNameDefault { file := core.Find(moduleSymbol.Declarations, ast.IsSourceFile) - if c.isOnlyImportableAsDefault(moduleSpecifier, moduleSymbol) || c.canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, moduleSpecifier) { + if c.isOnlyImportableAsDefault(moduleSpecifier, moduleSymbol, importAttributesType) || c.canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, moduleSpecifier) { symbolFromModule = c.resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) if symbolFromModule == nil { symbolFromModule = c.resolveSymbolEx(moduleSymbol, dontResolveAlias) @@ -14818,7 +14924,7 @@ func (c *Checker) getExternalModuleMember(node *ast.Node, specifier *ast.Node, d symbol = c.combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) } } - if ast.IsImportOrExportSpecifier(specifier) && c.isOnlyImportableAsDefault(moduleSpecifier, moduleSymbol) && nameText != ast.InternalSymbolNameDefault { + if ast.IsImportOrExportSpecifier(specifier) && c.isOnlyImportableAsDefault(moduleSpecifier, moduleSymbol, importAttributesType) && nameText != ast.InternalSymbolNameDefault { c.error(name, diagnostics.Named_imports_from_a_JSON_file_into_an_ECMAScript_module_are_not_allowed_when_module_is_set_to_0, c.moduleKind.String()) } else if symbol == nil { c.errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name) @@ -14891,13 +14997,13 @@ func (c *Checker) getExportOfModule(symbol *ast.Symbol, nameText string, specifi return nil } -func (c *Checker) isOnlyImportableAsDefault(usage *ast.Node, resolvedModule *ast.Symbol) bool { +func (c *Checker) isOnlyImportableAsDefault(usage *ast.Node, resolvedModule *ast.Symbol, importAttributesType *Type) bool { // In Node.js, JSON modules don't get named exports if core.ModuleKindNode16 <= c.moduleKind && c.moduleKind <= core.ModuleKindNodeNext { usageMode := c.getEmitSyntaxForModuleSpecifierExpression(usage) if usageMode == core.ModuleKindESNext { if resolvedModule == nil { - resolvedModule = c.resolveExternalModuleName(usage, usage, true /*ignoreErrors*/) + resolvedModule = c.resolveExternalModuleName(usage, usage, true /*ignoreErrors*/, importAttributesType) } var targetFile *ast.SourceFile if resolvedModule != nil { @@ -15047,7 +15153,7 @@ func (c *Checker) getTargetOfExportSpecifier(node *ast.Node, meaning ast.SymbolF if ast.ModuleExportNameIsDefault(name) { specifier := c.getModuleSpecifierForImportOrExport(node) if specifier != nil { - moduleSymbol := c.resolveExternalModuleName(node, specifier, false /*ignoreErrors*/) + moduleSymbol := c.resolveExternalModuleName(node, specifier, false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(node.Parent.Parent))) if moduleSymbol != nil { return c.getTargetOfModuleDefault(moduleSymbol, node, dontResolveAlias) } @@ -15150,7 +15256,7 @@ func getModuleSpecifierFromNode(node *ast.Node) *ast.Node { case ast.KindExportDeclaration: return node.ModuleSpecifier() } - panic("Unhandled case in getModuleSpecifierFromNode") + panic("Unhandled case in getModuleSpecifierFromNode: " + node.Kind.String()) } /** @@ -15192,13 +15298,13 @@ func (c *Checker) markSymbolOfAliasDeclarationIfTypeOnly(aliasDeclaration *ast.N return links.typeOnlyDeclaration != nil } -func (c *Checker) resolveExternalModuleName(location *ast.Node, moduleReferenceExpression *ast.Node, ignoreErrors bool) *ast.Symbol { +func (c *Checker) resolveExternalModuleName(location *ast.Node, moduleReferenceExpression *ast.Node, ignoreErrors bool, importAttributesType *Type) *ast.Symbol { errorMessage := c.getCannotResolveModuleNameErrorForSpecificModule(moduleReferenceExpression) if errorMessage == nil { errorMessage = diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations } ignoreErrors = ignoreErrors || c.compilerOptions.NoCheck.IsTrue() - return c.resolveExternalModuleNameWorker(location, moduleReferenceExpression, core.IfElse(ignoreErrors, nil, errorMessage), ignoreErrors, false /*isForAugmentation*/) + return c.resolveExternalModuleNameWorker(location, moduleReferenceExpression, core.IfElse(ignoreErrors, nil, errorMessage), ignoreErrors, false /*isForAugmentation*/, importAttributesType) } func (c *Checker) getCannotResolveModuleNameErrorForSpecificModule(moduleName *ast.Node) *diagnostics.Message { @@ -15213,9 +15319,9 @@ func (c *Checker) getCannotResolveModuleNameErrorForSpecificModule(moduleName *a return nil } -func (c *Checker) resolveExternalModuleNameWorker(location *ast.Node, moduleReferenceExpression *ast.Node, moduleNotFoundError *diagnostics.Message, ignoreErrors bool, isForAugmentation bool) *ast.Symbol { +func (c *Checker) resolveExternalModuleNameWorker(location *ast.Node, moduleReferenceExpression *ast.Node, moduleNotFoundError *diagnostics.Message, ignoreErrors bool, isForAugmentation bool, importAttributesType *Type) *ast.Symbol { if ast.IsStringLiteralLike(moduleReferenceExpression) { - return c.resolveExternalModule(location, moduleReferenceExpression.Text(), moduleNotFoundError, core.IfElse(!ignoreErrors, moduleReferenceExpression, nil), isForAugmentation) + return c.resolveExternalModule(location, moduleReferenceExpression.Text(), moduleNotFoundError, core.IfElse(!ignoreErrors, moduleReferenceExpression, nil), isForAugmentation, importAttributesType) } return nil } @@ -15229,7 +15335,11 @@ func (c *Checker) getExternalModuleFileFromDeclaration(declaration *ast.Node) *a } else { specifier = ast.GetExternalModuleName(declaration) } - moduleSymbol := c.resolveExternalModuleNameWorker(specifier, specifier /*moduleNotFoundError*/, nil, false, false) // TODO: GH#18217 + var importAttributesType *Type + if ast.HasImportAttributes(declaration) { + importAttributesType = c.getTypeFromImportAttributes(ast.GetImportAttributes(declaration)) + } + moduleSymbol := c.resolveExternalModuleNameWorker(specifier, specifier /*moduleNotFoundError*/, nil, false, false, importAttributesType) // TODO: GH#18217 if moduleSymbol == nil { return nil } @@ -15240,11 +15350,15 @@ func (c *Checker) getExternalModuleFileFromDeclaration(declaration *ast.Node) *a return decl.AsSourceFile() } -func (c *Checker) resolveExternalModule(location *ast.Node, moduleReference string, moduleNotFoundError *diagnostics.Message, errorNode *ast.Node, isForAugmentation bool) *ast.Symbol { +func (c *Checker) resolveExternalModule(location *ast.Node, moduleReference string, moduleNotFoundError *diagnostics.Message, errorNode *ast.Node, isForAugmentation bool, importAttributesType *Type) *ast.Symbol { if errorNode != nil && strings.HasPrefix(moduleReference, "@types/") { withoutAtTypePrefix := moduleReference[len("@types/"):] c.error(errorNode, diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1, withoutAtTypePrefix, moduleReference) } + if importAttributesType == nil { + importAttributesType = c.emptyObjectType + } + ambientModule := c.tryFindAmbientModule(moduleReference, true /*withAugmentations*/) if ambientModule != nil { return ambientModule @@ -15456,13 +15570,48 @@ func (c *Checker) resolveExternalModule(location *ast.Node, moduleReference stri } if len(c.patternAmbientModules) != 0 { - pattern := core.FindBestPatternMatch(c.patternAmbientModules, func(v *ast.PatternAmbientModule) core.Pattern { return v.Pattern }, moduleReference) - if pattern != nil { + candidates := core.Filter(c.patternAmbientModules, func(v *ast.PatternAmbientModule) bool { + moduleAttributesType := c.getTypeOfModuleImportAttributes(v.Symbol) + return v.Pattern.Matches(moduleReference) && c.isTypeAssignableTo(importAttributesType, moduleAttributesType) + }) + + if len(candidates) > 0 { augmentation := c.patternAmbientModuleAugmentations[moduleReference] - if augmentation != nil { + augmentationTarget := c.patternAmbientModuleAugmentationTargets[moduleReference] + + if len(candidates) == 1 { + mergedCandidate := c.getMergedSymbol(candidates[0].Symbol) + if augmentation != nil && augmentationTarget == mergedCandidate { + return c.getMergedSymbol(augmentation) + } + return mergedCandidate + } + + var bestTypeCandidates []*ast.PatternAmbientModule + outer: + for i, candidate := range candidates { + candidateType := c.getTypeOfModuleImportAttributes(candidate.Symbol) + for j, other := range candidates { + otherType := c.getTypeOfModuleImportAttributes(other.Symbol) + if i != j && c.isTypeStrictSubtypeOf(otherType, candidateType) && !c.isTypeIdenticalTo(otherType, candidateType) { + continue outer + } + } + bestTypeCandidates = append(bestTypeCandidates, candidate) + } + if len(bestTypeCandidates) == 1 { + mergedCandidate := c.getMergedSymbol(bestTypeCandidates[0].Symbol) + if augmentation != nil && augmentationTarget == mergedCandidate { + return c.getMergedSymbol(augmentation) + } + return mergedCandidate + } + pattern := core.FindBestPatternMatch(bestTypeCandidates, func(v *ast.PatternAmbientModule) core.Pattern { return v.Pattern }, moduleReference) + mergedCandidate := c.getMergedSymbol(pattern.Symbol) + if augmentation != nil && augmentationTarget == mergedCandidate { return c.getMergedSymbol(augmentation) } - return c.getMergedSymbol(pattern.Symbol) + return mergedCandidate } } @@ -15638,9 +15787,18 @@ func (c *Checker) tryFindAmbientModule(moduleName string, withAugmentations bool func (c *Checker) GetAmbientModules() []*ast.Symbol { c.ambientModulesOnce.Do(func() { + seen := make(map[*ast.Symbol]struct{}) for sym, global := range c.globals { if strings.HasPrefix(sym, "\"") && strings.HasSuffix(sym, "\"") { c.ambientModules = append(c.ambientModules, global) + seen[global] = struct{}{} + } + } + for _, module := range c.patternAmbientModules { + symbol := c.getMergedSymbol(module.Symbol) + if _, ok := seen[symbol]; !ok { + c.ambientModules = append(c.ambientModules, symbol) + seen[symbol] = struct{}{} } } }) @@ -15679,7 +15837,7 @@ func (c *Checker) resolveESModuleSymbol(moduleSymbol *ast.Symbol, node *ast.Node reference = referenceParent.ModuleSpecifier() } typ := c.getTypeOfSymbol(symbol) - defaultOnlyType := c.getTypeWithSyntheticDefaultOnly(typ, symbol, moduleSymbol, reference) + defaultOnlyType := c.getTypeWithSyntheticDefaultOnly(typ, symbol, moduleSymbol, reference, c.getImportAttributesTypeForModuleSpecifier(reference)) if defaultOnlyType != nil { return c.cloneTypeAsModuleType(symbol, defaultOnlyType, referenceParent) } @@ -15723,8 +15881,8 @@ func isESMFormatImportImportingCommonjsFormatFile(usageMode core.ResolutionMode, return usageMode == core.ModuleKindESNext && targetMode == core.ModuleKindCommonJS } -func (c *Checker) getTypeWithSyntheticDefaultOnly(t *Type, symbol *ast.Symbol, originalSymbol *ast.Symbol, moduleSpecifier *ast.Node) *Type { - hasDefaultOnly := c.isOnlyImportableAsDefault(moduleSpecifier, nil) +func (c *Checker) getTypeWithSyntheticDefaultOnly(t *Type, symbol *ast.Symbol, originalSymbol *ast.Symbol, moduleSpecifier *ast.Node, importAttributesType *Type) *Type { + hasDefaultOnly := c.isOnlyImportableAsDefault(moduleSpecifier, nil, importAttributesType) if hasDefaultOnly && t != nil && !c.isErrorType(t) { key := CachedTypeKey{kind: CachedTypeKindDefaultOnlyType, typeId: t.id} if cached := c.cachedTypes[key]; cached != nil { @@ -15934,7 +16092,7 @@ func (c *Checker) resolveQualifiedName(name *ast.Node, left *ast.Node, right *as namespace.ValueDeclaration.Initializer() != nil && c.isCommonJSRequire(namespace.ValueDeclaration.Initializer()) { moduleName := namespace.ValueDeclaration.Initializer().Arguments()[0] - moduleSym := c.resolveExternalModuleName(moduleName, moduleName, false /*ignoreErrors*/) + moduleSym := c.resolveExternalModuleName(moduleName, moduleName, false /*ignoreErrors*/, nil) if moduleSym != nil { resolvedModuleSymbol := c.resolveExternalModuleSymbol(moduleSym, false /*dontResolveAlias*/) if resolvedModuleSymbol != nil { @@ -16265,7 +16423,7 @@ func (c *Checker) getExportsOfModuleWorker(moduleSymbol *ast.Symbol) (exports as nestedSymbols := make(ast.SymbolTable) lookupTable := make(ExportCollisionTable) for _, node := range exportStars.Declarations { - resolvedModule := c.resolveExternalModuleName(node, node.ModuleSpecifier(), false /*ignoreErrors*/) + resolvedModule := c.resolveExternalModuleName(node, node.ModuleSpecifier(), false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(node))) exportedSymbols := visit(resolvedModule, node, isTypeOnly || node.IsTypeOnly()) c.extendExportSymbols(nestedSymbols, exportedSymbols, lookupTable, node) } @@ -24707,7 +24865,7 @@ func (c *Checker) getTypeFromImportTypeNode(node *ast.Node) *Type { } targetMeaning := core.IfElse(n.IsTypeOf, ast.SymbolFlagsValue, ast.SymbolFlagsType) // TODO: Future work: support unions/generics/whatever via a deferred import-type - innerModuleSymbol := c.resolveExternalModuleName(node, n.Argument.AsLiteralTypeNode().Literal, false /*ignoreErrors*/) + innerModuleSymbol := c.resolveExternalModuleName(node, n.Argument.AsLiteralTypeNode().Literal, false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(node))) if innerModuleSymbol == nil { c.symbolNodeLinks.Get(node).resolvedSymbol = c.unknownSymbol links.resolvedType = c.errorType @@ -28797,7 +28955,7 @@ func (c *Checker) resolveHelpersModule(file *ast.SourceFile, errorNode *ast.Node links := c.sourceFileLinks.Get(file) if links.externalHelpersModule == nil { location := c.program.GetImportHelpersImportSpecifier(file.Path()) - helpersModule := c.resolveExternalModule(location, externalHelpersModuleNameText, diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode, false /*isForAugmentation*/) + helpersModule := c.resolveExternalModule(location, externalHelpersModuleNameText, diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode, false /*isForAugmentation*/, nil /*importAttributesType*/) if helpersModule == nil { helpersModule = c.unknownSymbol } @@ -31812,7 +31970,7 @@ func (c *Checker) getSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Sy ((parent.Kind == ast.KindImportDeclaration || parent.Kind == ast.KindJSImportDeclaration || parent.Kind == ast.KindExportDeclaration) && ast.GetExternalModuleName(parent) == node) || ast.IsVariableDeclarationInitializedToRequire(grandParent) || ast.IsImportCall(parent) || (ast.IsLiteralTypeNode(parent) && ast.IsLiteralImportTypeNode(grandParent) && grandParent.AsImportTypeNode().Argument == parent) { - return c.resolveExternalModuleName(node, node, ignoreErrors) + return c.resolveExternalModuleName(node, node, ignoreErrors, c.getImportAttributesTypeForModuleSpecifier(node)) } if ast.IsCallExpression(parent) && ast.IsBindableObjectDefinePropertyCall(parent) && parent.Arguments()[1] == node { return c.getSymbolOfDeclaration(parent) @@ -32156,7 +32314,7 @@ func (c *Checker) getTypeOfNode(node *ast.Node) *Type { } if ast.IsImportAttributes(node) { - return c.getGlobalImportAttributesType() + return c.checkImportAttributesExpression(node) } return c.errorType diff --git a/tsc/internal/checker/checker_test.go b/tsc/internal/checker/checker_test.go index 891f8cca3e8af..131f3fd6b3f4a 100644 --- a/tsc/internal/checker/checker_test.go +++ b/tsc/internal/checker/checker_test.go @@ -1,6 +1,8 @@ package checker_test import ( + "slices" + "strings" "testing" "github.com/microsoft/TypeScript/tsc/internal/ast" @@ -56,3 +58,65 @@ foo.bar;` } } } + +func TestGetSymbolsInScopePatternAmbientModuleGroups(t *testing.T) { + t.Parallel() + + content := `declare module "*.variant" with { type: "css" } { + export const cssOnly: "css"; +} +declare module "*.variant" with { type: "text" } { + export const textOnly: "text"; +} +declare module "*.variant" with { type: "css" } { + export const cssAlso: "css-also"; +} +declare module "*.variant" with { type: "text" } { + export const textAlso: "text-also"; +} +const marker = 0;` + fs := vfstest.FromMap(map[string]string{ + "/foo.ts": content, + "/tsconfig.json": ` + { + "compilerOptions": { + "module": "preserve", + "moduleResolution": "bundler" + }, + "files": ["foo.ts"] + } + `, + }, false /*useCaseSensitiveFileNames*/) + fs = bundled.WrapFS(fs) + + host := compiler.NewCompilerHost("/", fs, bundled.LibPath(), nil, nil, nil) + parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, nil, host, nil) + assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line") + + p := compiler.NewProgram(compiler.ProgramOptions{ + Config: parsed, + Host: host, + }) + p.BindSourceFiles() + c, done := p.GetTypeChecker(t.Context()) + defer done() + file := p.GetSourceFile("/foo.ts") + marker := file.Statements.Nodes[4].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0].Name() + + var groups []string + for _, symbol := range c.GetSymbolsInScope(marker, ast.SymbolFlagsValueModule) { + if len(symbol.Declarations) == 0 || !ast.IsModuleWithStringLiteralName(symbol.Declarations[0]) || symbol.Declarations[0].Name().Text() != "*.variant" { + continue + } + assert.Assert(t, strings.HasPrefix(symbol.Name, "\"*.variant\""+ast.InternalSymbolNamePrefix+"pattern@")) + assert.Equal(t, len(symbol.Declarations), 2) + var exportNames []string + for _, exported := range c.GetExportsOfModule(symbol) { + exportNames = append(exportNames, exported.Name) + } + slices.Sort(exportNames) + groups = append(groups, strings.Join(exportNames, ",")) + } + slices.Sort(groups) + assert.DeepEqual(t, groups, []string{"cssAlso,cssOnly", "textAlso,textOnly"}) +} diff --git a/tsc/internal/checker/emitresolver.go b/tsc/internal/checker/emitresolver.go index 1a4f86696fd2a..9bc590fd179bf 100644 --- a/tsc/internal/checker/emitresolver.go +++ b/tsc/internal/checker/emitresolver.go @@ -1155,13 +1155,6 @@ func (r *EmitResolver) GetEffectiveDeclarationFlags(node *ast.Node, flags ast.Mo return r.checker.GetEffectiveDeclarationFlags(node, flags) } -func (r *EmitResolver) GetResolutionModeOverride(node *ast.Node) core.ResolutionMode { - // node = emitContext.ParseNode(node) - r.checkerMu.Lock() - defer r.checkerMu.Unlock() - return r.checker.GetResolutionModeOverride(node.AsImportAttributes(), false) -} - func (r *EmitResolver) GetConstantValue(node *ast.Node) any { // node = emitContext.ParseNode(node) r.checkerMu.Lock() diff --git a/tsc/internal/checker/exports.go b/tsc/internal/checker/exports.go index 49efc3208d430..6e0160a1d10ff 100644 --- a/tsc/internal/checker/exports.go +++ b/tsc/internal/checker/exports.go @@ -2,7 +2,6 @@ package checker import ( "github.com/microsoft/TypeScript/tsc/internal/ast" - "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/diagnostics" ) @@ -117,8 +116,8 @@ func (c *Checker) GetTypeOnlyAliasDeclaration(symbol *ast.Symbol) *ast.Node { return c.getTypeOnlyAliasDeclaration(symbol) } -func (c *Checker) ResolveExternalModuleName(moduleSpecifier *ast.Node) *ast.Symbol { - return c.resolveExternalModuleName(moduleSpecifier, moduleSpecifier, true /*ignoreErrors*/) +func (c *Checker) ResolveExternalModuleName(moduleSpecifier *ast.Node, importAttributesType *Type) *ast.Symbol { + return c.resolveExternalModuleName(moduleSpecifier, moduleSpecifier, true /*ignoreErrors*/, importAttributesType) } func (c *Checker) ResolveExternalModuleSymbol(moduleSymbol *ast.Symbol) *ast.Symbol { @@ -197,10 +196,6 @@ func (c *Checker) GetDefaultFromTypeParameter(typeParameter *Type) *Type { return c.getDefaultFromTypeParameter(typeParameter) } -func (c *Checker) GetResolutionModeOverride(node *ast.ImportAttributes, reportErrors bool) core.ResolutionMode { - return c.getResolutionModeOverride(node, reportErrors) -} - func (c *Checker) GetEffectiveDeclarationFlags(n *ast.Node, flagsToCheck ast.ModifierFlags) ast.ModifierFlags { return c.getEffectiveDeclarationFlags(n, flagsToCheck) } diff --git a/tsc/internal/checker/jsx.go b/tsc/internal/checker/jsx.go index bb7415912db3d..7b2d448ed8814 100644 --- a/tsc/internal/checker/jsx.go +++ b/tsc/internal/checker/jsx.go @@ -1474,7 +1474,7 @@ func (c *Checker) getJsxNamespaceContainerForImplicitImport(location *ast.Node) return nil } errorMessage := diagnostics.This_JSX_tag_requires_the_module_path_0_to_exist_but_none_could_be_found_Make_sure_you_have_types_for_the_appropriate_package_installed - mod := c.resolveExternalModule(core.OrElse(specifier, canonicalErrorTag), moduleReference, errorMessage, canonicalErrorTag, false) + mod := c.resolveExternalModule(core.OrElse(specifier, canonicalErrorTag), moduleReference, errorMessage, canonicalErrorTag, false, nil /*importAttributesType*/) var result *ast.Symbol if mod != nil && mod != c.unknownSymbol { result = c.getMergedSymbol(c.resolveSymbol(mod)) diff --git a/tsc/internal/checker/nodebuilder_hover.go b/tsc/internal/checker/nodebuilder_hover.go index fd5cd55f2b0a7..d07e229b20451 100644 --- a/tsc/internal/checker/nodebuilder_hover.go +++ b/tsc/internal/checker/nodebuilder_hover.go @@ -8,6 +8,7 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/jsnum" "github.com/microsoft/TypeScript/tsc/internal/nodebuilder" + "github.com/microsoft/TypeScript/tsc/internal/printer" "github.com/microsoft/TypeScript/tsc/internal/scanner" ) @@ -499,7 +500,7 @@ func (b *NodeBuilderImpl) expandModuleDecl(symbol *ast.Symbol) *ast.Node { merged := b.ch.getMergedSymbol(resolved) hasModuleExports := merged.Flags&(ast.SymbolFlagsValueModule|ast.SymbolFlagsNamespaceModule) != 0 && merged.Exports != nil && len(merged.Exports) != 0 if !hasModuleExports { - bodyStmts = append(bodyStmts, hoverStatement{node: b.f.NewModuleDeclaration(nil, ast.KindNamespaceKeyword, b.f.NewIdentifier(m.Name), b.f.NewModuleBlock(b.f.NewNodeList(nil)))}) + bodyStmts = append(bodyStmts, hoverStatement{node: b.f.NewModuleDeclaration(nil, ast.KindNamespaceKeyword, b.f.NewIdentifier(m.Name), nil /*attributes*/, b.f.NewModuleBlock(b.f.NewNodeList(nil)))}) } continue } @@ -543,7 +544,14 @@ func (b *NodeBuilderImpl) expandModuleDecl(symbol *ast.Symbol) *ast.Node { if !ast.IsIdentifier(localName) { keyword = ast.KindModuleKeyword } - return b.f.NewModuleDeclaration(nil, keyword, localName, b.f.NewModuleBlock(b.f.NewNodeList(bodyStatements))) + var attributes *ast.TypeLiteralNodeNode + if declaration := core.Find(symbol.Declarations, func(declaration *ast.Node) bool { + return ast.IsModuleDeclaration(declaration) && declaration.AsModuleDeclaration().Attributes != nil + }); declaration != nil { + attributes = b.f.DeepCloneNode(declaration.AsModuleDeclaration().Attributes) + b.e.SetEmitFlags(attributes, printer.EFSingleLine) + } + return b.f.NewModuleDeclaration(nil, keyword, localName, attributes, b.f.NewModuleBlock(b.f.NewNodeList(bodyStatements))) } // serializeTypeAliasForNamespace produces a TypeAliasDeclaration for a type alias inside a namespace body. diff --git a/tsc/internal/checker/nodebuilderimpl.go b/tsc/internal/checker/nodebuilderimpl.go index 53007b500e8c6..948129838cffb 100644 --- a/tsc/internal/checker/nodebuilderimpl.go +++ b/tsc/internal/checker/nodebuilderimpl.go @@ -1258,6 +1258,9 @@ func (b *NodeBuilderImpl) getSpecifierForModuleSymbol(symbol *ast.Symbol, overri } if file == nil { + if declaration := core.Find(symbol.Declarations, ast.IsModuleWithStringLiteralName); declaration != nil { + return declaration.Name().Text() + } if ast.IsAmbientModuleSymbolName(symbol.Name) { return stringutil.StripQuotes(symbol.Name) } diff --git a/tsc/internal/checker/nodecopy.go b/tsc/internal/checker/nodecopy.go index 4f567ed7bd50e..7f9f2423e1c04 100644 --- a/tsc/internal/checker/nodecopy.go +++ b/tsc/internal/checker/nodecopy.go @@ -235,7 +235,7 @@ func (b *NodeBuilderImpl) getModuleSpecifierOverride(parent *ast.Node, lit *ast. if b.ctx.enclosingFile != ast.GetSourceFileOfNode(lit) { mode := core.ResolutionModeNone if parent.AsImportTypeNode().Attributes != nil { - mode = b.ch.getResolutionModeOverride(parent.AsImportTypeNode().Attributes.AsImportAttributes(), false) + mode, _ = parent.AsImportTypeNode().Attributes.AsImportAttributes().GetResolutionModeOverride(nil) } name := lit.Text() originalName := name diff --git a/tsc/internal/checker/symbolaccessibility.go b/tsc/internal/checker/symbolaccessibility.go index 5bfacafaf1ad6..d19806d50599d 100644 --- a/tsc/internal/checker/symbolaccessibility.go +++ b/tsc/internal/checker/symbolaccessibility.go @@ -187,7 +187,7 @@ func (c *Checker) getAlternativeContainingModules(symbol *ast.Symbol, enclosingD // Synthetic names can't be resolved by `resolveExternalModuleName` - they'll cause a debug assert if they error continue } - resolvedModule := c.resolveExternalModuleName(enclosingDeclaration, importRef /*ignoreErrors*/, true) + resolvedModule := c.resolveExternalModuleName(enclosingDeclaration, importRef /*ignoreErrors*/, true, c.getImportAttributesTypeForModuleSpecifier(importRef)) if resolvedModule == nil { continue } diff --git a/tsc/internal/compiler/emitHost.go b/tsc/internal/compiler/emitHost.go index eef782917fcd6..e6d4e1ce153d0 100644 --- a/tsc/internal/compiler/emitHost.go +++ b/tsc/internal/compiler/emitHost.go @@ -100,10 +100,6 @@ func (host *emitHost) SourceFileMayBeEmitted(file *ast.SourceFile, forceDtsEmit return sourceFileMayBeEmitted(file, host, forceDtsEmit, false) } -func (host *emitHost) GetResolutionModeOverride(node *ast.Node) core.ResolutionMode { - return host.GetEmitResolver().GetResolutionModeOverride(node) -} - func (host *emitHost) GetSourceFileFromReference(origin *ast.SourceFile, ref *ast.FileReference) *ast.SourceFile { return host.program.GetSourceFileFromReference(origin, ref) } diff --git a/tsc/internal/compiler/fileloader.go b/tsc/internal/compiler/fileloader.go index c89d06051692c..6f4bed1a73919 100644 --- a/tsc/internal/compiler/fileloader.go +++ b/tsc/internal/compiler/fileloader.go @@ -1019,11 +1019,11 @@ func getModeForUsageLocation(fileName string, meta ast.SourceFileMetaData, usage var ok bool switch usage.Parent.Kind { case ast.KindImportDeclaration, ast.KindJSImportDeclaration: - override, ok = usage.Parent.AsImportDeclaration().Attributes.GetResolutionModeOverride() + override, ok = usage.Parent.AsImportDeclaration().Attributes.GetResolutionModeOverride(nil) case ast.KindExportDeclaration: - override, ok = usage.Parent.AsExportDeclaration().Attributes.GetResolutionModeOverride() + override, ok = usage.Parent.AsExportDeclaration().Attributes.GetResolutionModeOverride(nil) case ast.KindJSDocImportTag: - override, ok = usage.Parent.AsJSDocImportTag().Attributes.GetResolutionModeOverride() + override, ok = usage.Parent.AsJSDocImportTag().Attributes.GetResolutionModeOverride(nil) } if ok { return override @@ -1031,7 +1031,7 @@ func getModeForUsageLocation(fileName string, meta ast.SourceFileMetaData, usage } } if ast.IsLiteralTypeNode(usage.Parent) && ast.IsImportTypeNode(usage.Parent.Parent) { - if override, ok := usage.Parent.Parent.AsImportTypeNode().Attributes.GetResolutionModeOverride(); ok { + if override, ok := usage.Parent.Parent.AsImportTypeNode().Attributes.GetResolutionModeOverride(nil); ok { return override } } diff --git a/tsc/internal/diagnostics/diagnostics_generated.go b/tsc/internal/diagnostics/diagnostics_generated.go index 5c53bdcbb2641..bae5270108132 100644 --- a/tsc/internal/diagnostics/diagnostics_generated.go +++ b/tsc/internal/diagnostics/diagnostics_generated.go @@ -932,6 +932,10 @@ var X_await_using_declarations_are_not_allowed_in_case_or_default_clauses_unless var Ignore_the_tsconfig_found_and_build_with_commandline_options_and_files = &Message{code: 1549, category: CategoryMessage, key: "Ignore_the_tsconfig_found_and_build_with_commandline_options_and_files_1549", text: "Ignore the tsconfig found and build with commandline options and files."} +var An_ambient_module_declaration_with_import_attributes_must_use_a_pattern_name_with_an_Asterisk_character = &Message{code: 1550, category: CategoryError, key: "An_ambient_module_declaration_with_import_attributes_must_use_a_pattern_name_with_an_Asterisk_charac_1550", text: "An ambient module declaration with import attributes must use a pattern name with an '*' character."} + +var Import_attributes_are_not_allowed_on_a_module_augmentation = &Message{code: 1551, category: CategoryError, key: "Import_attributes_are_not_allowed_on_a_module_augmentation_1551", text: "Import attributes are not allowed on a module augmentation."} + var The_types_of_0_are_incompatible_between_these_types = &Message{code: 2200, category: CategoryError, key: "The_types_of_0_are_incompatible_between_these_types_2200", text: "The types of '{0}' are incompatible between these types."} var The_types_returned_by_0_are_incompatible_between_these_types = &Message{code: 2201, category: CategoryError, key: "The_types_returned_by_0_are_incompatible_between_these_types_2201", text: "The types returned by '{0}' are incompatible between these types."} @@ -5346,6 +5350,10 @@ func keyToMessage(key Key) *Message { return X_await_using_declarations_are_not_allowed_in_case_or_default_clauses_unless_contained_within_a_block case "Ignore_the_tsconfig_found_and_build_with_commandline_options_and_files_1549": return Ignore_the_tsconfig_found_and_build_with_commandline_options_and_files + case "An_ambient_module_declaration_with_import_attributes_must_use_a_pattern_name_with_an_Asterisk_charac_1550": + return An_ambient_module_declaration_with_import_attributes_must_use_a_pattern_name_with_an_Asterisk_character + case "Import_attributes_are_not_allowed_on_a_module_augmentation_1551": + return Import_attributes_are_not_allowed_on_a_module_augmentation case "The_types_of_0_are_incompatible_between_these_types_2200": return The_types_of_0_are_incompatible_between_these_types case "The_types_returned_by_0_are_incompatible_between_these_types_2201": diff --git a/tsc/internal/diagnostics/extraDiagnosticMessages.json b/tsc/internal/diagnostics/extraDiagnosticMessages.json index 3fe74485cb7fe..7a55976ce2807 100644 --- a/tsc/internal/diagnostics/extraDiagnosticMessages.json +++ b/tsc/internal/diagnostics/extraDiagnosticMessages.json @@ -75,9 +75,13 @@ "category": "Error", "code": 6048 }, - "Ignore the tsconfig found and build with commandline options and files.": { - "category": "Message", - "code": 1549 + "An ambient module declaration with import attributes must use a pattern name with an '*' character.": { + "category": "Error", + "code": 1550 + }, + "Import attributes are not allowed on a module augmentation.": { + "category": "Error", + "code": 1551 }, "tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.": { "category": "Error", diff --git a/tsc/internal/fourslash/tests/autoImportPatternAmbientModule_test.go b/tsc/internal/fourslash/tests/autoImportPatternAmbientModule_test.go new file mode 100644 index 0000000000000..e3b9568387e9b --- /dev/null +++ b/tsc/internal/fourslash/tests/autoImportPatternAmbientModule_test.go @@ -0,0 +1,43 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/fourslash" + . "github.com/microsoft/TypeScript/tsc/internal/fourslash/tests/util" + "github.com/microsoft/TypeScript/tsc/internal/testutil" +) + +// Auto-imports ignores +func TestAutoImportMergedPatternAmbientModule(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ "compilerOptions": { "module": "preserve", "moduleResolution": "bundler" } } + +// @Filename: /first.d.ts +declare module "*.asset" with { type: "css" } { + export const styles: string; +} + +// @Filename: /second.d.ts +declare module "*.asset" with { type: "css" } { + export const styleTokens: string; +} + +// @Filename: /index.ts +sty/**/` + + f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) + defer done() + f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{ + IsIncomplete: false, + ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{ + CommitCharacters: &DefaultCommitCharacters, + EditRange: Ignored, + }, + Items: &fourslash.CompletionsExpectedItems{ + Excludes: []string{"styles", "styleTokens"}, + }, + }) +} diff --git a/tsc/internal/fourslash/tests/quickInfoAmbientModule_test.go b/tsc/internal/fourslash/tests/quickInfoAmbientModule_test.go index 8fb06fd3c4379..bca7ec8ec64a0 100644 --- a/tsc/internal/fourslash/tests/quickInfoAmbientModule_test.go +++ b/tsc/internal/fourslash/tests/quickInfoAmbientModule_test.go @@ -17,3 +17,42 @@ func TestQuickInfoAmbientModule(t *testing.T) { defer done() f.VerifyQuickInfoAt(t, "1", `module "*.css"`, "") } + +func TestQuickInfoPatternAmbientModuleWithImportAttributes(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `declare module "*.css"/*1*/ with { type: "css" } { + const styles: { readonly [className: string]: string }; + export default styles; +}` + + f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) + defer done() + f.VerifyBaselineHoverWithVerbosity(t, map[string][]int{"1": {0, 1}}) +} + +func TestQuickInfoMergedPatternAmbientModuleWithImportAttributes(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /first.d.ts +declare module "*.asset"/*css*/ with { type: "css" } { + export const cssOnly: "css"; +} +declare module "*.asset"/*text*/ with { type: "text" } { + export const textOnly: "text"; +} + +// @Filename: /second.d.ts +declare module "*.asset" with { type: "css" } { + export const cssAlso: "css-also"; +} +declare module "*.asset" with { type: "text" } { + export const textAlso: "text-also"; +}` + + f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) + defer done() + f.VerifyBaselineHoverWithVerbosity(t, map[string][]int{"css": {0, 1}, "text": {0, 1}}) +} diff --git a/tsc/internal/ls/autoimport/fix.go b/tsc/internal/ls/autoimport/fix.go index a035f305eaf1d..0c5240c6f6539 100644 --- a/tsc/internal/ls/autoimport/fix.go +++ b/tsc/internal/ls/autoimport/fix.go @@ -858,7 +858,7 @@ func (v *View) getExistingImports(ctx context.Context) *collections.MultiMap[Mod if node == nil { panic("error: did not expect node kind " + moduleSpecifier.Kind.String()) } else if ast.IsVariableDeclarationInitializedToRequire(node.Parent) { - if moduleSymbol := ch.ResolveExternalModuleName(moduleSpecifier); moduleSymbol != nil { + if moduleSymbol := ch.ResolveExternalModuleName(moduleSpecifier, nil /*importAttributesType*/); moduleSymbol != nil { if moduleID, _, ok := tryGetModuleIDAndFileNameOfModuleSymbol(moduleSymbol); ok { result.Add(moduleID, existingImport{node: node.Parent, moduleSpecifier: moduleSpecifier.Text(), index: i}) } diff --git a/tsc/internal/ls/codeactions_fixmissingtypeannotation.go b/tsc/internal/ls/codeactions_fixmissingtypeannotation.go index 8aa78f151b9ea..50bea6bd45d9a 100644 --- a/tsc/internal/ls/codeactions_fixmissingtypeannotation.go +++ b/tsc/internal/ls/codeactions_fixmissingtypeannotation.go @@ -295,6 +295,7 @@ func (f *isolatedDeclarationsFixer) createNamespaceForExpandoProperties(expandoF factory.NewModifierList(modifiers), ast.KindNamespaceKeyword, factory.NewIdentifier(funcDecl.Name().Text()), + nil, /*attributes*/ factory.NewModuleBlock(factory.NewNodeList(newProperties)), ) // Set the flags for namespace diff --git a/tsc/internal/ls/hover.go b/tsc/internal/ls/hover.go index 13fc132e0f026..7d766977e6ed6 100644 --- a/tsc/internal/ls/hover.go +++ b/tsc/internal/ls/hover.go @@ -465,6 +465,22 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol text := c.SymbolToStringEx(symbol, enclosing, meaning, flags) dpw.WriteSymbol(text, symbol) } + writeModuleImportAttributes := func(symbol *ast.Symbol) { + declaration := core.Find(symbol.Declarations, func(declaration *ast.Node) bool { + return ast.IsModuleDeclaration(declaration) && declaration.AsModuleDeclaration().Attributes != nil + }) + if declaration == nil { + return + } + attributes := declaration.AsModuleDeclaration().Attributes + emitContext := printer.NewEmitContext() + emitContext.SetEmitFlags(attributes, printer.EFSingleLine) + p := printer.NewPrinter(printer.PrinterOptions{NewLine: core.NewLineKindLF}, printer.PrintHandlers{}, emitContext) + tempDpw := newDisplayPartsWriter(vsCapability) + p.Write(attributes, ast.GetSourceFileOfNode(declaration), tempDpw, nil) + dpw.WriteKeyword(" with ") + dpw.WriteFrom(tempDpw) + } if node.Kind == ast.KindThisKeyword && ast.IsInExpressionContext(node) || ast.IsThisInTypeQuery(node) { dpw.WriteKeyword("this") dpw.WritePunctuation(": ") @@ -801,6 +817,7 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol isModule := symbol.ValueDeclaration != nil && (ast.IsSourceFile(symbol.ValueDeclaration) || ast.IsAmbientModule(symbol.ValueDeclaration)) dpw.WriteKeyword(core.IfElse(isModule, "module ", "namespace ")) writeSymbolClassified(symbol, container, ast.SymbolFlagsNone, symbolFormatFlags) + writeModuleImportAttributes(symbol) } setDeclaration(core.Find(symbol.Declarations, ast.IsModuleDeclaration)) } diff --git a/tsc/internal/ls/string_completions.go b/tsc/internal/ls/string_completions.go index e7580a55cdd00..9f8dd24cdc16d 100644 --- a/tsc/internal/ls/string_completions.go +++ b/tsc/internal/ls/string_completions.go @@ -905,7 +905,7 @@ func getAmbientModuleCompletions(fragment string, fragmentDirectory string, type ambientModules := typeChecker.GetAmbientModules() var nonRelativeModuleNames []string for _, sym := range ambientModules { - moduleName := stringutil.StripQuotes(sym.Name) + moduleName := getAmbientModuleName(sym) if strings.HasPrefix(moduleName, fragment) && !strings.Contains(moduleName, "*") { nonRelativeModuleNames = append(nonRelativeModuleNames, moduleName) } @@ -920,6 +920,14 @@ func getAmbientModuleCompletions(fragment string, fragmentDirectory string, type return nonRelativeModuleNames } +func getAmbientModuleName(symbol *ast.Symbol) string { + declaration := ast.GetNonAugmentationDeclaration(symbol) + if declaration != nil && ast.IsModuleWithStringLiteralName(declaration) { + return declaration.Name().Text() + } + return stringutil.StripQuotes(symbol.Name) +} + func (l *LanguageService) getCompletionEntriesFromTypings( program *compiler.Program, scriptPath string, @@ -1045,7 +1053,7 @@ func getSupportedExtensionsForModuleResolution(options *core.CompilerOptions, ex if checker != nil { ambientModules := checker.GetAmbientModules() for _, module := range ambientModules { - name := stringutil.StripQuotes(module.Name) + name := getAmbientModuleName(module) if !strings.HasPrefix(name, "*.") || strings.Contains(name, "/") { continue } diff --git a/tsc/internal/parser/jsdoc.go b/tsc/internal/parser/jsdoc.go index bd55bd03a2d8e..6d239d2f228fc 100644 --- a/tsc/internal/parser/jsdoc.go +++ b/tsc/internal/parser/jsdoc.go @@ -1001,6 +1001,7 @@ func (p *Parser) parseJSDocTypeNameWithNamespace(nested bool) *ast.Node { nil, /*modifiers*/ ast.KindNamespaceKeyword, /*keyword*/ typeNameOrNamespaceName, + nil, /*attributes*/ body, ) if nested { diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index 8b53a39b0cda3..8eef8b7a7da8d 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -2227,13 +2227,17 @@ func (p *Parser) parseAmbientExternalModuleDeclaration(pos int, jsdoc jsdocScann // parse string literal name = p.parseLiteralExpression() } + var attributes *ast.TypeLiteralNodeNode + if keyword == ast.KindModuleKeyword && p.parseOptional(ast.KindWithKeyword) { + attributes = p.parseTypeLiteral() + } var body *ast.Node if p.token == ast.KindOpenBraceToken { body = p.parseModuleBlock() } else { p.parseSemicolon() } - result := p.finishNode(p.factory.NewModuleDeclaration(modifiers, keyword, name, body), pos) + result := p.finishNode(p.factory.NewModuleDeclaration(modifiers, keyword, name, attributes, body), pos) p.withJSDoc(result, jsdoc) p.statementHasAwaitIdentifier = saveHasAwaitIdentifier return result @@ -2269,7 +2273,7 @@ func (p *Parser) parseModuleOrNamespaceDeclaration(pos int, jsdoc jsdocScannerIn } else { body = p.parseModuleBlock() } - result := p.finishNode(p.factory.NewModuleDeclaration(modifiers, keyword, name, body), pos) + result := p.finishNode(p.factory.NewModuleDeclaration(modifiers, keyword, name, nil, body), pos) p.withJSDoc(result, jsdoc) p.checkJSSyntax(result) p.statementHasAwaitIdentifier = saveHasAwaitIdentifier diff --git a/tsc/internal/parser/reparser.go b/tsc/internal/parser/reparser.go index fce97c480286c..b1f5b705f090b 100644 --- a/tsc/internal/parser/reparser.go +++ b/tsc/internal/parser/reparser.go @@ -741,7 +741,7 @@ func (p *Parser) wrapInJSDocNamespace(fullName *ast.Node, statement *ast.Node, n if nested { modifiers = p.createExportModifier(fullName) } - result := p.factory.NewModuleDeclaration(modifiers, ast.KindNamespaceKeyword, p.addDeepCloneReparse(fullName.Name()), block) + result := p.factory.NewModuleDeclaration(modifiers, ast.KindNamespaceKeyword, p.addDeepCloneReparse(fullName.Name()), nil, block) p.finishReparsedNode(result, fullName) p.reparsedClones = append(p.reparsedClones, result) return result diff --git a/tsc/internal/printer/emitresolver.go b/tsc/internal/printer/emitresolver.go index e6b60e801ed94..f9b98dba994ce 100644 --- a/tsc/internal/printer/emitresolver.go +++ b/tsc/internal/printer/emitresolver.go @@ -3,7 +3,6 @@ package printer import ( "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/binder" - "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/evaluator" "github.com/microsoft/TypeScript/tsc/internal/nodebuilder" ) @@ -82,7 +81,6 @@ type EmitResolver interface { MarkLinkedReferencesRecursively(file *ast.SourceFile) GetExternalModuleFileFromDeclaration(node *ast.Node) *ast.SourceFile GetEffectiveDeclarationFlags(node *ast.Node, flags ast.ModifierFlags) ast.ModifierFlags - GetResolutionModeOverride(node *ast.Node) core.ResolutionMode // decorator metadata GetTypeReferenceSerializationKind(name *ast.EntityName, serialScope *ast.Node) TypeReferenceSerializationKind diff --git a/tsc/internal/printer/printer.go b/tsc/internal/printer/printer.go index 6f0386780975f..7a359fe74a4dc 100644 --- a/tsc/internal/printer/printer.go +++ b/tsc/internal/printer/printer.go @@ -3837,6 +3837,12 @@ func (p *Printer) emitModuleDeclaration(node *ast.ModuleDeclaration) { p.emitNestedModuleName(module.Name()) body = module.Body } + if node.Attributes != nil { + p.writeSpace() + p.writeKeyword("with") + p.writeSpace() + p.emitTypeNode(node.Attributes, ast.TypePrecedenceNonArray) + } if body == nil { p.writeTrailingSemicolon() } else { diff --git a/tsc/internal/testrunner/compiler_runner.go b/tsc/internal/testrunner/compiler_runner.go index 16bd2e4fe52e8..39bae630829c8 100644 --- a/tsc/internal/testrunner/compiler_runner.go +++ b/tsc/internal/testrunner/compiler_runner.go @@ -197,7 +197,7 @@ func (r *CompilerBaselineRunner) runTest(t *testing.T, filename string) { func (r *CompilerBaselineRunner) runSingleConfigTest(t *testing.T, testName string, test *compilerFileBasedTest, config *harnessutil.NamedTestConfiguration) { t.Parallel() - defer testutil.RecoverAndFail(t, "Panic on compiling test "+test.filename) + defer testutil.RecoverAndFail(t, "Panic on compiler test "+test.filename) payload := makeUnitsFromTest(test.content, test.filename) compilerTest := newCompilerTest(t, testName, test.filename, &payload, config) diff --git a/tsc/internal/transformers/declarations/transform.go b/tsc/internal/transformers/declarations/transform.go index 08e26b96a82fd..32fa0201a9ef5 100644 --- a/tsc/internal/transformers/declarations/transform.go +++ b/tsc/internal/transformers/declarations/transform.go @@ -39,7 +39,6 @@ type DeclarationEmitHost interface { GetOutputPathsFor(file *ast.SourceFile, forceDtsPaths bool) OutputPaths SourceFileMayBeEmitted(file *ast.SourceFile, forceDtsEmit bool) bool - GetResolutionModeOverride(node *ast.Node) core.ResolutionMode GetEffectiveDeclarationFlags(node *ast.Node, flags ast.ModifierFlags) ast.ModifierFlags GetEmitResolver() printer.EmitResolver } @@ -1165,7 +1164,7 @@ func (tx *DeclarationTransformer) visitDeclarationStatements(input *ast.Node) *a input.IsTypeOnly(), input.AsExportDeclaration().ExportClause, tx.rewriteModuleSpecifier(input, input.ModuleSpecifier()), - tx.tryGetResolutionModeOverride(input.AsExportDeclaration().Attributes), + input.AsExportDeclaration().Attributes, ) case ast.KindExportAssignment: return tx.transformExportAssignment(input, input, input.Expression(), input.AsExportAssignment().IsExportEquals) @@ -1396,6 +1395,7 @@ func (tx *DeclarationTransformer) transformCommonJSExportWorker(input *ast.Node, tx.Factory().NewModifierList(nsMods), ast.KindNamespaceKeyword, nsName, + nil, tx.Factory().NewModuleBlock(tx.Factory().NewNodeList([]*ast.Node{classDecl})), ) @@ -1543,6 +1543,7 @@ func (tx *DeclarationTransformer) wrapInCJSExportNamespace(content *ast.Node) *a tx.Factory().NewModifierList(nsMods), ast.KindNamespaceKeyword, nsName, + nil, tx.Factory().NewModuleBlock(tx.Factory().NewNodeList(members)), ) } @@ -1594,17 +1595,6 @@ func (tx *DeclarationTransformer) rewriteModuleSpecifier(parent *ast.Node, input return input } -func (tx *DeclarationTransformer) tryGetResolutionModeOverride(node *ast.Node) *ast.Node { - if node == nil { - return node - } - mode := tx.host.GetResolutionModeOverride(node) - if mode != core.ResolutionModeNone { - return node - } - return nil -} - func (tx *DeclarationTransformer) preserveJsDoc(updated *ast.Node, original *ast.Node) { // Copy comment range from original to updated node so JSDoc comments are preserved tx.EmitContext().AssignCommentRange(updated, original) @@ -1838,6 +1828,7 @@ func (tx *DeclarationTransformer) transformModuleDeclaration(input *ast.ModuleDe if keyword != ast.KindGlobalKeyword && (input.Name() == nil || !ast.IsStringLiteral(input.Name())) { keyword = ast.KindNamespaceKeyword } + attributes := tx.Visitor().Visit(input.Attributes) if inner != nil && inner.Kind == ast.KindModuleBlock { oldNeedsScopeFix := tx.needsScopeFixMarker @@ -1871,6 +1862,7 @@ func (tx *DeclarationTransformer) transformModuleDeclaration(input *ast.ModuleDe mods, keyword, input.Name(), + attributes, body, ) } @@ -1887,6 +1879,7 @@ func (tx *DeclarationTransformer) transformModuleDeclaration(input *ast.ModuleDe mods, keyword, input.Name(), + attributes, body, ) } @@ -1895,6 +1888,7 @@ func (tx *DeclarationTransformer) transformModuleDeclaration(input *ast.ModuleDe mods, keyword, input.Name(), + attributes, nil, ) } @@ -2479,7 +2473,7 @@ func (tx *DeclarationTransformer) transformImportDeclaration(decl *ast.ImportDec decl.Modifiers(), decl.ImportClause, tx.rewriteModuleSpecifier(decl.AsNode(), decl.ModuleSpecifier), - tx.tryGetResolutionModeOverride(decl.Attributes), + decl.Attributes, ) } phaseModifier := decl.ImportClause.AsImportClause().PhaseModifier @@ -2506,7 +2500,7 @@ func (tx *DeclarationTransformer) transformImportDeclaration(decl *ast.ImportDec /*namedBindings*/ nil, ), tx.rewriteModuleSpecifier(decl.AsNode(), decl.ModuleSpecifier), - tx.tryGetResolutionModeOverride(decl.Attributes), + decl.Attributes, ) } if decl.ImportClause.AsImportClause().NamedBindings.Kind == ast.KindNamespaceImport { @@ -2528,7 +2522,7 @@ func (tx *DeclarationTransformer) transformImportDeclaration(decl *ast.ImportDec namedBindings, ), tx.rewriteModuleSpecifier(decl.AsNode(), decl.ModuleSpecifier), - tx.tryGetResolutionModeOverride(decl.Attributes), + decl.Attributes, ) } // Named imports (optionally with visible default) @@ -2556,7 +2550,7 @@ func (tx *DeclarationTransformer) transformImportDeclaration(decl *ast.ImportDec namedImports, ), tx.rewriteModuleSpecifier(decl.AsNode(), decl.ModuleSpecifier), - tx.tryGetResolutionModeOverride(decl.Attributes), + decl.Attributes, ) } // Augmentation of export depends on import @@ -2569,7 +2563,7 @@ func (tx *DeclarationTransformer) transformImportDeclaration(decl *ast.ImportDec decl.Modifiers(), /*importClause*/ nil, tx.rewriteModuleSpecifier(decl.AsNode(), decl.ModuleSpecifier), - tx.tryGetResolutionModeOverride(decl.Attributes), + decl.Attributes, ) } // Nothing visible @@ -2808,7 +2802,7 @@ func (tx *DeclarationTransformer) transformExpandoAssignment(node *ast.BinaryExp varModifiers = tx.Factory().NewModifierList(ast.CreateModifiersFromModifierFlags(ast.ModifierFlagsExport, tx.Factory().NewModifier)) } - synthesizedNamespace := tx.Factory().NewModuleDeclaration(nil /*modifiers*/, ast.KindNamespaceKeyword, name, tx.Factory().NewModuleBlock(tx.Factory().NewNodeList([]*ast.Node{}))) + synthesizedNamespace := tx.Factory().NewModuleDeclaration(nil /*modifiers*/, ast.KindNamespaceKeyword, name, nil, tx.Factory().NewModuleBlock(tx.Factory().NewNodeList([]*ast.Node{}))) synthesizedNamespace.Parent = tx.enclosingDeclaration declarationData := synthesizedNamespace.DeclarationData() declarationData.Symbol = host @@ -2955,6 +2949,7 @@ func (tx *DeclarationTransformer) createFullExpandoBlock(id ast.NodeId) *ast.Nod modifiers, ast.KindNamespaceKeyword, name, + nil, tx.Factory().NewModuleBlock(tx.Factory().NewNodeList(addOns)), ) members := append(host, moduleDecl) diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.errors.txt b/tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.errors.txt new file mode 100644 index 0000000000000..261ada3c1a0f7 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.errors.txt @@ -0,0 +1,17 @@ +/index.ts(3,7): error TS2339: Property 'ambient' does not exist on type 'typeof import("/file.d.ext")'. + + +==== /types.d.ts (0 errors) ==== + declare module "*.ext" with { type: "custom" } { + export const ambient: "ambient"; + } + +==== /file.d.ext.ts (0 errors) ==== + export const physical: "physical"; + +==== /index.ts (1 errors) ==== + import * as value from "./file.ext" with { type: "custom" }; + value.physical; + value.ambient; + ~~~~~~~ +!!! error TS2339: Property 'ambient' does not exist on type 'typeof import("/file.d.ext")'. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.symbols b/tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.symbols new file mode 100644 index 0000000000000..0442d1f98ae6f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.symbols @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/importAttributeArbitraryExtension.ts] //// + +=== /types.d.ts === +declare module "*.ext" with { type: "custom" } { +>"*.ext" : Symbol("*.ext", Decl(types.d.ts, 0, 0)) +>type : Symbol(type, Decl(types.d.ts, 0, 29)) + + export const ambient: "ambient"; +>ambient : Symbol(ambient, Decl(types.d.ts, 1, 16)) +} + +=== /file.d.ext.ts === +export const physical: "physical"; +>physical : Symbol(physical, Decl(file.d.ext.ts, 0, 12)) + +=== /index.ts === +import * as value from "./file.ext" with { type: "custom" }; +>value : Symbol(value, Decl(index.ts, 0, 6)) + +value.physical; +>value.physical : Symbol(value.physical, Decl(file.d.ext.ts, 0, 12)) +>value : Symbol(value, Decl(index.ts, 0, 6)) +>physical : Symbol(value.physical, Decl(file.d.ext.ts, 0, 12)) + +value.ambient; +>value : Symbol(value, Decl(index.ts, 0, 6)) + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.types b/tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.types new file mode 100644 index 0000000000000..65ca155c5856a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeArbitraryExtension.types @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/importAttributeArbitraryExtension.ts] //// + +=== /types.d.ts === +declare module "*.ext" with { type: "custom" } { +>"*.ext" : typeof import("*.ext") +>type : "custom" + + export const ambient: "ambient"; +>ambient : "ambient" +} + +=== /file.d.ext.ts === +export const physical: "physical"; +>physical : "physical" + +=== /index.ts === +import * as value from "./file.ext" with { type: "custom" }; +>value : typeof value +>type : any + +value.physical; +>value.physical : "physical" +>value : typeof value +>physical : "physical" + +value.ambient; +>value.ambient : any +>value : typeof value +>ambient : any + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeDuplicatePatternMergedResolution.symbols b/tsc/testdata/baselines/reference/compiler/importAttributeDuplicatePatternMergedResolution.symbols new file mode 100644 index 0000000000000..0c0b14177f903 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeDuplicatePatternMergedResolution.symbols @@ -0,0 +1,107 @@ +//// [tests/cases/compiler/importAttributeDuplicatePatternMergedResolution.ts] //// + +=== /a.d.ts === +declare module "*.asset" with { type: "css", format: "module" } { +>"*.asset" : Symbol("*.asset", Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0)) +>type : Symbol(type, Decl(a.d.ts, 0, 31)) +>format : Symbol(format, Decl(a.d.ts, 0, 44)) + + export const fromA: "a"; +>fromA : Symbol(fromA, Decl(a.d.ts, 1, 16)) +} + +=== /b.d.ts === +declare module "*.asset" with { format: "module", type: "css" } { +>"*.asset" : Symbol("*.asset", Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0)) +>format : Symbol(format, Decl(b.d.ts, 0, 31)) +>type : Symbol(type, Decl(b.d.ts, 0, 49)) + + export const fromB: "b"; +>fromB : Symbol(fromB, Decl(b.d.ts, 1, 16)) +} + +=== /variantsA.d.ts === +declare module "*.variant" with { type: "css" } { +>"*.variant" : Symbol("*.variant", Decl(variantsA.d.ts, 0, 0), Decl(variantsB.d.ts, 0, 0)) +>type : Symbol(type, Decl(variantsA.d.ts, 0, 33)) + + export const cssOnly: "css"; +>cssOnly : Symbol(cssOnly, Decl(variantsA.d.ts, 1, 16)) +} + +declare module "*.variant" with { type: "text" } { +>"*.variant" : Symbol("*.variant", Decl(variantsA.d.ts, 2, 1), Decl(variantsB.d.ts, 2, 1)) +>type : Symbol(type, Decl(variantsA.d.ts, 4, 33)) + + export const textOnly: "text"; +>textOnly : Symbol(textOnly, Decl(variantsA.d.ts, 5, 16)) +} + +=== /variantsB.d.ts === +declare module "*.variant" with { type: "css" } { +>"*.variant" : Symbol("*.variant", Decl(variantsA.d.ts, 0, 0), Decl(variantsB.d.ts, 0, 0)) +>type : Symbol(type, Decl(variantsB.d.ts, 0, 33)) + + export const cssAlso: "css-also"; +>cssAlso : Symbol(cssAlso, Decl(variantsB.d.ts, 1, 16)) +} + +declare module "*.variant" with { type: "text" } { +>"*.variant" : Symbol("*.variant", Decl(variantsA.d.ts, 2, 1), Decl(variantsB.d.ts, 2, 1)) +>type : Symbol(type, Decl(variantsB.d.ts, 4, 33)) + + export const textAlso: "text-also"; +>textAlso : Symbol(textAlso, Decl(variantsB.d.ts, 5, 16)) +} + +=== /index.ts === +import { fromA, fromB } from "./file.asset" with { type: "css", format: "module" }; +>fromA : Symbol(fromA, Decl(index.ts, 0, 8)) +>fromB : Symbol(fromB, Decl(index.ts, 0, 15)) + +import * as css from "./file.variant" with { type: "css" }; +>css : Symbol(css, Decl(index.ts, 1, 6)) + +import * as text from "./file.variant" with { type: "text" }; +>text : Symbol(text, Decl(index.ts, 2, 6)) + +const a: "a" = fromA; +>a : Symbol(a, Decl(index.ts, 4, 5)) +>fromA : Symbol(fromA, Decl(index.ts, 0, 8)) + +const b: "b" = fromB; +>b : Symbol(b, Decl(index.ts, 5, 5)) +>fromB : Symbol(fromB, Decl(index.ts, 0, 15)) + +const cssValue: "css" = css.cssOnly; +>cssValue : Symbol(cssValue, Decl(index.ts, 6, 5)) +>css.cssOnly : Symbol(css.cssOnly, Decl(variantsA.d.ts, 1, 16)) +>css : Symbol(css, Decl(index.ts, 1, 6)) +>cssOnly : Symbol(css.cssOnly, Decl(variantsA.d.ts, 1, 16)) + +const cssAlsoValue: "css-also" = css.cssAlso; +>cssAlsoValue : Symbol(cssAlsoValue, Decl(index.ts, 7, 5)) +>css.cssAlso : Symbol(css.cssAlso, Decl(variantsB.d.ts, 1, 16)) +>css : Symbol(css, Decl(index.ts, 1, 6)) +>cssAlso : Symbol(css.cssAlso, Decl(variantsB.d.ts, 1, 16)) + +const textValue: "text" = text.textOnly; +>textValue : Symbol(textValue, Decl(index.ts, 8, 5)) +>text.textOnly : Symbol(text.textOnly, Decl(variantsA.d.ts, 5, 16)) +>text : Symbol(text, Decl(index.ts, 2, 6)) +>textOnly : Symbol(text.textOnly, Decl(variantsA.d.ts, 5, 16)) + +const textAlsoValue: "text-also" = text.textAlso; +>textAlsoValue : Symbol(textAlsoValue, Decl(index.ts, 9, 5)) +>text.textAlso : Symbol(text.textAlso, Decl(variantsB.d.ts, 5, 16)) +>text : Symbol(text, Decl(index.ts, 2, 6)) +>textAlso : Symbol(text.textAlso, Decl(variantsB.d.ts, 5, 16)) + +const cssDoesNotHaveText: "textOnly" extends keyof typeof css ? false : true = true; +>cssDoesNotHaveText : Symbol(cssDoesNotHaveText, Decl(index.ts, 11, 5)) +>css : Symbol(css, Decl(index.ts, 1, 6)) + +const textDoesNotHaveCss: "cssOnly" extends keyof typeof text ? false : true = true; +>textDoesNotHaveCss : Symbol(textDoesNotHaveCss, Decl(index.ts, 12, 5)) +>text : Symbol(text, Decl(index.ts, 2, 6)) + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeDuplicatePatternMergedResolution.types b/tsc/testdata/baselines/reference/compiler/importAttributeDuplicatePatternMergedResolution.types new file mode 100644 index 0000000000000..136834e8faf0f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeDuplicatePatternMergedResolution.types @@ -0,0 +1,117 @@ +//// [tests/cases/compiler/importAttributeDuplicatePatternMergedResolution.ts] //// + +=== /a.d.ts === +declare module "*.asset" with { type: "css", format: "module" } { +>"*.asset" : typeof import("*.asset") +>type : "css" +>format : "module" + + export const fromA: "a"; +>fromA : "a" +} + +=== /b.d.ts === +declare module "*.asset" with { format: "module", type: "css" } { +>"*.asset" : typeof import("*.asset") +>format : "module" +>type : "css" + + export const fromB: "b"; +>fromB : "b" +} + +=== /variantsA.d.ts === +declare module "*.variant" with { type: "css" } { +>"*.variant" : typeof import("*.variant") +>type : "css" + + export const cssOnly: "css"; +>cssOnly : "css" +} + +declare module "*.variant" with { type: "text" } { +>"*.variant" : typeof import("*.variant") +>type : "text" + + export const textOnly: "text"; +>textOnly : "text" +} + +=== /variantsB.d.ts === +declare module "*.variant" with { type: "css" } { +>"*.variant" : typeof import("*.variant") +>type : "css" + + export const cssAlso: "css-also"; +>cssAlso : "css-also" +} + +declare module "*.variant" with { type: "text" } { +>"*.variant" : typeof import("*.variant") +>type : "text" + + export const textAlso: "text-also"; +>textAlso : "text-also" +} + +=== /index.ts === +import { fromA, fromB } from "./file.asset" with { type: "css", format: "module" }; +>fromA : "a" +>fromB : "b" +>type : error +>format : error + +import * as css from "./file.variant" with { type: "css" }; +>css : typeof css +>type : error + +import * as text from "./file.variant" with { type: "text" }; +>text : typeof text +>type : error + +const a: "a" = fromA; +>a : "a" +>fromA : "a" + +const b: "b" = fromB; +>b : "b" +>fromB : "b" + +const cssValue: "css" = css.cssOnly; +>cssValue : "css" +>css.cssOnly : "css" +>css : typeof css +>cssOnly : "css" + +const cssAlsoValue: "css-also" = css.cssAlso; +>cssAlsoValue : "css-also" +>css.cssAlso : "css-also" +>css : typeof css +>cssAlso : "css-also" + +const textValue: "text" = text.textOnly; +>textValue : "text" +>text.textOnly : "text" +>text : typeof text +>textOnly : "text" + +const textAlsoValue: "text-also" = text.textAlso; +>textAlsoValue : "text-also" +>text.textAlso : "text-also" +>text : typeof text +>textAlso : "text-also" + +const cssDoesNotHaveText: "textOnly" extends keyof typeof css ? false : true = true; +>cssDoesNotHaveText : true +>css : typeof css +>false : false +>true : true +>true : true + +const textDoesNotHaveCss: "cssOnly" extends keyof typeof text ? false : true = true; +>textDoesNotHaveCss : true +>text : typeof text +>false : false +>true : true +>true : true + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeDynamicImports.symbols b/tsc/testdata/baselines/reference/compiler/importAttributeDynamicImports.symbols new file mode 100644 index 0000000000000..8ca3622b06292 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeDynamicImports.symbols @@ -0,0 +1,95 @@ +//// [tests/cases/compiler/importAttributeDynamicImports.ts] //// + +=== /types.d.ts === +declare module "*.resource" { +>"*.resource" : Symbol("*.resource", Decl(types.d.ts, 0, 0)) + + export const kind: "plain"; +>kind : Symbol(kind, Decl(types.d.ts, 1, 16)) +} + +declare module "typed/*.resource" with { type: "text" } { +>"typed/*.resource" : Symbol("typed/*.resource", Decl(types.d.ts, 2, 1)) +>type : Symbol(type, Decl(types.d.ts, 4, 40)) + + export const kind: "text"; +>kind : Symbol(kind, Decl(types.d.ts, 5, 16)) +} + +=== /index.ts === +async function test() { +>test : Symbol(test, Decl(index.ts, 0, 0)) + + const plain = await import("plain.resource"); +>plain : Symbol(plain, Decl(index.ts, 1, 9)) +>"plain.resource" : Symbol("*.resource", Decl(types.d.ts, 0, 0)) + + const plainKind: "plain" = plain.kind; +>plainKind : Symbol(plainKind, Decl(index.ts, 2, 9)) +>plain.kind : Symbol(kind, Decl(types.d.ts, 1, 16)) +>plain : Symbol(plain, Decl(index.ts, 1, 9)) +>kind : Symbol(kind, Decl(types.d.ts, 1, 16)) + + const attributed = await import("typed/file.resource", { with: { type: "text" } }); +>attributed : Symbol(attributed, Decl(index.ts, 4, 9)) +>"typed/file.resource" : Symbol("typed/*.resource", Decl(types.d.ts, 2, 1)) +>with : Symbol(with, Decl(index.ts, 4, 60)) +>type : Symbol(type, Decl(index.ts, 4, 68)) + + const attributedKind: "text" = attributed.kind; +>attributedKind : Symbol(attributedKind, Decl(index.ts, 5, 9)) +>attributed.kind : Symbol(kind, Decl(types.d.ts, 5, 16)) +>attributed : Symbol(attributed, Decl(index.ts, 4, 9)) +>kind : Symbol(kind, Decl(types.d.ts, 5, 16)) + + const parenthesized = await import("typed/parenthesized.resource", ({ with: { type: "text" } })); +>parenthesized : Symbol(parenthesized, Decl(index.ts, 7, 9)) +>"typed/parenthesized.resource" : Symbol("typed/*.resource", Decl(types.d.ts, 2, 1)) +>with : Symbol(with, Decl(index.ts, 7, 73)) +>type : Symbol(type, Decl(index.ts, 7, 81)) + + const parenthesizedKind: "text" = parenthesized.kind; +>parenthesizedKind : Symbol(parenthesizedKind, Decl(index.ts, 8, 9)) +>parenthesized.kind : Symbol(kind, Decl(types.d.ts, 5, 16)) +>parenthesized : Symbol(parenthesized, Decl(index.ts, 7, 9)) +>kind : Symbol(kind, Decl(types.d.ts, 5, 16)) + + const options = { with: { type: "text" as const } }; +>options : Symbol(options, Decl(index.ts, 10, 9)) +>with : Symbol(with, Decl(index.ts, 10, 21)) +>type : Symbol(type, Decl(index.ts, 10, 29)) +>const : Symbol(const) + + const attributedWithOptions = await import("typed/other.resource", options); +>attributedWithOptions : Symbol(attributedWithOptions, Decl(index.ts, 11, 9)) +>"typed/other.resource" : Symbol("typed/*.resource", Decl(types.d.ts, 2, 1)) +>options : Symbol(options, Decl(index.ts, 10, 9)) + + const attributedWithOptionsKind: "text" = attributedWithOptions.kind; +>attributedWithOptionsKind : Symbol(attributedWithOptionsKind, Decl(index.ts, 12, 9)) +>attributedWithOptions.kind : Symbol(kind, Decl(types.d.ts, 5, 16)) +>attributedWithOptions : Symbol(attributedWithOptions, Decl(index.ts, 11, 9)) +>kind : Symbol(kind, Decl(types.d.ts, 5, 16)) + + const withoutAttributes = await import("typed/unattributed.resource"); +>withoutAttributes : Symbol(withoutAttributes, Decl(index.ts, 14, 9)) +>"typed/unattributed.resource" : Symbol("*.resource", Decl(types.d.ts, 0, 0)) + + const withoutAttributesKind: "plain" = withoutAttributes.kind; +>withoutAttributesKind : Symbol(withoutAttributesKind, Decl(index.ts, 15, 9)) +>withoutAttributes.kind : Symbol(kind, Decl(types.d.ts, 1, 16)) +>withoutAttributes : Symbol(withoutAttributes, Decl(index.ts, 14, 9)) +>kind : Symbol(kind, Decl(types.d.ts, 1, 16)) + + const unmatchedAttributes = await import("fallback.resource", { with: { type: "unknown" } }); +>unmatchedAttributes : Symbol(unmatchedAttributes, Decl(index.ts, 17, 9)) +>"fallback.resource" : Symbol("*.resource", Decl(types.d.ts, 0, 0)) +>with : Symbol(with, Decl(index.ts, 17, 67)) +>type : Symbol(type, Decl(index.ts, 17, 75)) + + const unmatchedAttributesKind: "plain" = unmatchedAttributes.kind; +>unmatchedAttributesKind : Symbol(unmatchedAttributesKind, Decl(index.ts, 18, 9)) +>unmatchedAttributes.kind : Symbol(kind, Decl(types.d.ts, 1, 16)) +>unmatchedAttributes : Symbol(unmatchedAttributes, Decl(index.ts, 17, 9)) +>kind : Symbol(kind, Decl(types.d.ts, 1, 16)) +} diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeDynamicImports.types b/tsc/testdata/baselines/reference/compiler/importAttributeDynamicImports.types new file mode 100644 index 0000000000000..9c22b106c51a1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeDynamicImports.types @@ -0,0 +1,120 @@ +//// [tests/cases/compiler/importAttributeDynamicImports.ts] //// + +=== /types.d.ts === +declare module "*.resource" { +>"*.resource" : typeof import("*.resource") + + export const kind: "plain"; +>kind : "plain" +} + +declare module "typed/*.resource" with { type: "text" } { +>"typed/*.resource" : typeof import("typed/*.resource") +>type : "text" + + export const kind: "text"; +>kind : "text" +} + +=== /index.ts === +async function test() { +>test : () => Promise + + const plain = await import("plain.resource"); +>plain : { kind: "plain"; default: typeof import("*.resource"); } +>await import("plain.resource") : { kind: "plain"; default: typeof import("*.resource"); } +>import("plain.resource") : Promise<{ kind: "plain"; default: typeof import("*.resource"); }> +>"plain.resource" : "plain.resource" + + const plainKind: "plain" = plain.kind; +>plainKind : "plain" +>plain.kind : "plain" +>plain : { kind: "plain"; default: typeof import("*.resource"); } +>kind : "plain" + + const attributed = await import("typed/file.resource", { with: { type: "text" } }); +>attributed : { kind: "text"; default: typeof import("typed/*.resource"); } +>await import("typed/file.resource", { with: { type: "text" } }) : { kind: "text"; default: typeof import("typed/*.resource"); } +>import("typed/file.resource", { with: { type: "text" } }) : Promise<{ kind: "text"; default: typeof import("typed/*.resource"); }> +>"typed/file.resource" : "typed/file.resource" +>{ with: { type: "text" } } : { with: { readonly type: "text"; }; } +>with : { readonly type: "text"; } +>{ type: "text" } : { readonly type: "text"; } +>type : "text" +>"text" : "text" + + const attributedKind: "text" = attributed.kind; +>attributedKind : "text" +>attributed.kind : "text" +>attributed : { kind: "text"; default: typeof import("typed/*.resource"); } +>kind : "text" + + const parenthesized = await import("typed/parenthesized.resource", ({ with: { type: "text" } })); +>parenthesized : { kind: "text"; default: typeof import("typed/*.resource"); } +>await import("typed/parenthesized.resource", ({ with: { type: "text" } })) : { kind: "text"; default: typeof import("typed/*.resource"); } +>import("typed/parenthesized.resource", ({ with: { type: "text" } })) : Promise<{ kind: "text"; default: typeof import("typed/*.resource"); }> +>"typed/parenthesized.resource" : "typed/parenthesized.resource" +>({ with: { type: "text" } }) : { with: { readonly type: "text"; }; } +>{ with: { type: "text" } } : { with: { readonly type: "text"; }; } +>with : { readonly type: "text"; } +>{ type: "text" } : { readonly type: "text"; } +>type : "text" +>"text" : "text" + + const parenthesizedKind: "text" = parenthesized.kind; +>parenthesizedKind : "text" +>parenthesized.kind : "text" +>parenthesized : { kind: "text"; default: typeof import("typed/*.resource"); } +>kind : "text" + + const options = { with: { type: "text" as const } }; +>options : { with: { type: "text"; }; } +>{ with: { type: "text" as const } } : { with: { type: "text"; }; } +>with : { type: "text"; } +>{ type: "text" as const } : { type: "text"; } +>type : "text" +>"text" as const : "text" +>"text" : "text" + + const attributedWithOptions = await import("typed/other.resource", options); +>attributedWithOptions : { kind: "text"; default: typeof import("typed/*.resource"); } +>await import("typed/other.resource", options) : { kind: "text"; default: typeof import("typed/*.resource"); } +>import("typed/other.resource", options) : Promise<{ kind: "text"; default: typeof import("typed/*.resource"); }> +>"typed/other.resource" : "typed/other.resource" +>options : { with: { type: "text"; }; } + + const attributedWithOptionsKind: "text" = attributedWithOptions.kind; +>attributedWithOptionsKind : "text" +>attributedWithOptions.kind : "text" +>attributedWithOptions : { kind: "text"; default: typeof import("typed/*.resource"); } +>kind : "text" + + const withoutAttributes = await import("typed/unattributed.resource"); +>withoutAttributes : { kind: "plain"; default: typeof import("*.resource"); } +>await import("typed/unattributed.resource") : { kind: "plain"; default: typeof import("*.resource"); } +>import("typed/unattributed.resource") : Promise<{ kind: "plain"; default: typeof import("*.resource"); }> +>"typed/unattributed.resource" : "typed/unattributed.resource" + + const withoutAttributesKind: "plain" = withoutAttributes.kind; +>withoutAttributesKind : "plain" +>withoutAttributes.kind : "plain" +>withoutAttributes : { kind: "plain"; default: typeof import("*.resource"); } +>kind : "plain" + + const unmatchedAttributes = await import("fallback.resource", { with: { type: "unknown" } }); +>unmatchedAttributes : { kind: "plain"; default: typeof import("*.resource"); } +>await import("fallback.resource", { with: { type: "unknown" } }) : { kind: "plain"; default: typeof import("*.resource"); } +>import("fallback.resource", { with: { type: "unknown" } }) : Promise<{ kind: "plain"; default: typeof import("*.resource"); }> +>"fallback.resource" : "fallback.resource" +>{ with: { type: "unknown" } } : { with: { readonly type: "unknown"; }; } +>with : { readonly type: "unknown"; } +>{ type: "unknown" } : { readonly type: "unknown"; } +>type : "unknown" +>"unknown" : "unknown" + + const unmatchedAttributesKind: "plain" = unmatchedAttributes.kind; +>unmatchedAttributesKind : "plain" +>unmatchedAttributes.kind : "plain" +>unmatchedAttributes : { kind: "plain"; default: typeof import("*.resource"); } +>kind : "plain" +} diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.errors.txt b/tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.errors.txt new file mode 100644 index 0000000000000..d299611097e5b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.errors.txt @@ -0,0 +1,51 @@ +/augmentations.ts(11,16): error TS2664: Invalid module name in augmentation, module 'unattributed.special' cannot be found. +/index.ts(7,12): error TS2339: Property 'augmented' does not exist on type 'typeof import("attributed/*.asset")'. +/index.ts(9,31): error TS2307: Cannot find module 'unattributed.special' or its corresponding type declarations. + + +==== /types.d.ts (0 errors) ==== + declare module "*.asset" { + export const plain: "plain"; + } + + declare module "attributed/*.asset" with { type: "css" } { + export const attributed: "attributed"; + } + + declare module "*.special" with { type: "special" } { + export const attributed: "attributed"; + } + +==== /augmentations.ts (1 errors) ==== + export {}; + + declare module "merged.asset" { + export const augmented: "augmented"; + } + + declare module "attributed/file.asset" { + export const augmented: "augmented"; + } + + declare module "unattributed.special" { + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2664: Invalid module name in augmentation, module 'unattributed.special' cannot be found. + export const augmented: "augmented"; + } + +==== /index.ts (2 errors) ==== + import * as merged from "merged.asset"; + merged.plain; + merged.augmented; + + import * as attributed from "attributed/file.asset" with { type: "css" }; + attributed.attributed; + attributed.augmented; + ~~~~~~~~~ +!!! error TS2339: Property 'augmented' does not exist on type 'typeof import("attributed/*.asset")'. + + import * as unattributed from "unattributed.special"; + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'unattributed.special' or its corresponding type declarations. + unattributed.attributed; + unattributed.augmented; \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.symbols b/tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.symbols new file mode 100644 index 0000000000000..9d6c49fe957ff --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.symbols @@ -0,0 +1,84 @@ +//// [tests/cases/compiler/importAttributeModuleAugmentations.ts] //// + +=== /types.d.ts === +declare module "*.asset" { +>"*.asset" : Symbol("*.asset", Decl(types.d.ts, 0, 0)) + + export const plain: "plain"; +>plain : Symbol(plain, Decl(types.d.ts, 1, 16)) +} + +declare module "attributed/*.asset" with { type: "css" } { +>"attributed/*.asset" : Symbol("attributed/*.asset", Decl(types.d.ts, 2, 1)) +>type : Symbol(type, Decl(types.d.ts, 4, 42)) + + export const attributed: "attributed"; +>attributed : Symbol(attributed, Decl(types.d.ts, 5, 16)) +} + +declare module "*.special" with { type: "special" } { +>"*.special" : Symbol("*.special", Decl(types.d.ts, 6, 1)) +>type : Symbol(type, Decl(types.d.ts, 8, 33)) + + export const attributed: "attributed"; +>attributed : Symbol(attributed, Decl(types.d.ts, 9, 16)) +} + +=== /augmentations.ts === +export {}; + +declare module "merged.asset" { +>"merged.asset" : Symbol("merged.asset", Decl(augmentations.ts, 0, 10), Decl(types.d.ts, 0, 0)) + + export const augmented: "augmented"; +>augmented : Symbol(augmented, Decl(augmentations.ts, 3, 16)) +} + +declare module "attributed/file.asset" { +>"attributed/file.asset" : Symbol("attributed/file.asset", Decl(augmentations.ts, 4, 1), Decl(types.d.ts, 0, 0)) + + export const augmented: "augmented"; +>augmented : Symbol(augmented, Decl(augmentations.ts, 7, 16)) +} + +declare module "unattributed.special" { +>"unattributed.special" : Symbol("unattributed.special", Decl(augmentations.ts, 8, 1)) + + export const augmented: "augmented"; +>augmented : Symbol(augmented, Decl(augmentations.ts, 11, 16)) +} + +=== /index.ts === +import * as merged from "merged.asset"; +>merged : Symbol(merged, Decl(index.ts, 0, 6)) + +merged.plain; +>merged.plain : Symbol(merged.plain, Decl(types.d.ts, 1, 16)) +>merged : Symbol(merged, Decl(index.ts, 0, 6)) +>plain : Symbol(merged.plain, Decl(types.d.ts, 1, 16)) + +merged.augmented; +>merged.augmented : Symbol(merged.augmented, Decl(augmentations.ts, 3, 16)) +>merged : Symbol(merged, Decl(index.ts, 0, 6)) +>augmented : Symbol(merged.augmented, Decl(augmentations.ts, 3, 16)) + +import * as attributed from "attributed/file.asset" with { type: "css" }; +>attributed : Symbol(attributed, Decl(index.ts, 4, 6)) + +attributed.attributed; +>attributed.attributed : Symbol(attributed.attributed, Decl(types.d.ts, 5, 16)) +>attributed : Symbol(attributed, Decl(index.ts, 4, 6)) +>attributed : Symbol(attributed.attributed, Decl(types.d.ts, 5, 16)) + +attributed.augmented; +>attributed : Symbol(attributed, Decl(index.ts, 4, 6)) + +import * as unattributed from "unattributed.special"; +>unattributed : Symbol(unattributed, Decl(index.ts, 8, 6)) + +unattributed.attributed; +>unattributed : Symbol(unattributed, Decl(index.ts, 8, 6)) + +unattributed.augmented; +>unattributed : Symbol(unattributed, Decl(index.ts, 8, 6)) + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.types b/tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.types new file mode 100644 index 0000000000000..e262a5a6d4875 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeModuleAugmentations.types @@ -0,0 +1,91 @@ +//// [tests/cases/compiler/importAttributeModuleAugmentations.ts] //// + +=== /types.d.ts === +declare module "*.asset" { +>"*.asset" : typeof import("*.asset") + + export const plain: "plain"; +>plain : "plain" +} + +declare module "attributed/*.asset" with { type: "css" } { +>"attributed/*.asset" : typeof import("attributed/*.asset") +>type : "css" + + export const attributed: "attributed"; +>attributed : "attributed" +} + +declare module "*.special" with { type: "special" } { +>"*.special" : typeof import("*.special") +>type : "special" + + export const attributed: "attributed"; +>attributed : "attributed" +} + +=== /augmentations.ts === +export {}; + +declare module "merged.asset" { +>"merged.asset" : typeof import("merged.asset") + + export const augmented: "augmented"; +>augmented : "augmented" +} + +declare module "attributed/file.asset" { +>"attributed/file.asset" : typeof import("attributed/file.asset") + + export const augmented: "augmented"; +>augmented : "augmented" +} + +declare module "unattributed.special" { +>"unattributed.special" : typeof import("unattributed.special") + + export const augmented: "augmented"; +>augmented : "augmented" +} + +=== /index.ts === +import * as merged from "merged.asset"; +>merged : typeof merged + +merged.plain; +>merged.plain : "plain" +>merged : typeof merged +>plain : "plain" + +merged.augmented; +>merged.augmented : "augmented" +>merged : typeof merged +>augmented : "augmented" + +import * as attributed from "attributed/file.asset" with { type: "css" }; +>attributed : typeof attributed +>type : any + +attributed.attributed; +>attributed.attributed : "attributed" +>attributed : typeof attributed +>attributed : "attributed" + +attributed.augmented; +>attributed.augmented : any +>attributed : typeof attributed +>augmented : any + +import * as unattributed from "unattributed.special"; +>unattributed : any + +unattributed.attributed; +>unattributed.attributed : any +>unattributed : any +>attributed : any + +unattributed.augmented; +>unattributed.augmented : any +>unattributed : any +>augmented : any + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeMostSpecificType.symbols b/tsc/testdata/baselines/reference/compiler/importAttributeMostSpecificType.symbols new file mode 100644 index 0000000000000..587e746ba36d6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeMostSpecificType.symbols @@ -0,0 +1,70 @@ +//// [tests/cases/compiler/importAttributeMostSpecificType.ts] //// + +=== /bun-sqlite.d.ts === +declare module "databases/*.sqlite" with { type: "sqlite" } { +>"databases/*.sqlite" : Symbol("databases/*.sqlite", Decl(bun-sqlite.d.ts, 0, 0)) +>type : Symbol(type, Decl(bun-sqlite.d.ts, 0, 42)) + + const database: { +>database : Symbol(database, Decl(bun-sqlite.d.ts, 1, 9)) + + storage: "external"; +>storage : Symbol(storage, Decl(bun-sqlite.d.ts, 1, 21)) + + filename: string; +>filename : Symbol(filename, Decl(bun-sqlite.d.ts, 2, 28)) + + }; + export default database; +>database : Symbol(database, Decl(bun-sqlite.d.ts, 1, 9)) +} + +declare module "*.sqlite" with { type: "sqlite", embed: "true" } { +>"*.sqlite" : Symbol("*.sqlite", Decl(bun-sqlite.d.ts, 6, 1)) +>type : Symbol(type, Decl(bun-sqlite.d.ts, 8, 32)) +>embed : Symbol(embed, Decl(bun-sqlite.d.ts, 8, 48)) + + const database: { +>database : Symbol(database, Decl(bun-sqlite.d.ts, 9, 9)) + + storage: "embedded"; +>storage : Symbol(storage, Decl(bun-sqlite.d.ts, 9, 21)) + + contents: Uint8Array; +>contents : Symbol(contents, Decl(bun-sqlite.d.ts, 10, 28)) +>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 3 more) + + }; + export default database; +>database : Symbol(database, Decl(bun-sqlite.d.ts, 9, 9)) +} + +=== /index.ts === +import externalDatabase from "databases/app.sqlite" with { type: "sqlite" }; +>externalDatabase : Symbol(externalDatabase, Decl(index.ts, 0, 6)) + +import embeddedDatabase from "databases/app.sqlite" with { type: "sqlite", embed: "true" }; +>embeddedDatabase : Symbol(embeddedDatabase, Decl(index.ts, 1, 6)) + +const expectedExternalStorage: "external" = externalDatabase.storage; +>expectedExternalStorage : Symbol(expectedExternalStorage, Decl(index.ts, 3, 5)) +>externalDatabase.storage : Symbol(storage, Decl(bun-sqlite.d.ts, 1, 21)) +>externalDatabase : Symbol(externalDatabase, Decl(index.ts, 0, 6)) +>storage : Symbol(storage, Decl(bun-sqlite.d.ts, 1, 21)) + +const expectedEmbeddedStorage: "embedded" = embeddedDatabase.storage; +>expectedEmbeddedStorage : Symbol(expectedEmbeddedStorage, Decl(index.ts, 4, 5)) +>embeddedDatabase.storage : Symbol(storage, Decl(bun-sqlite.d.ts, 9, 21)) +>embeddedDatabase : Symbol(embeddedDatabase, Decl(index.ts, 1, 6)) +>storage : Symbol(storage, Decl(bun-sqlite.d.ts, 9, 21)) + +externalDatabase.filename; +>externalDatabase.filename : Symbol(filename, Decl(bun-sqlite.d.ts, 2, 28)) +>externalDatabase : Symbol(externalDatabase, Decl(index.ts, 0, 6)) +>filename : Symbol(filename, Decl(bun-sqlite.d.ts, 2, 28)) + +embeddedDatabase.contents; +>embeddedDatabase.contents : Symbol(contents, Decl(bun-sqlite.d.ts, 10, 28)) +>embeddedDatabase : Symbol(embeddedDatabase, Decl(index.ts, 1, 6)) +>contents : Symbol(contents, Decl(bun-sqlite.d.ts, 10, 28)) + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeMostSpecificType.types b/tsc/testdata/baselines/reference/compiler/importAttributeMostSpecificType.types new file mode 100644 index 0000000000000..78d8f82526e2d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeMostSpecificType.types @@ -0,0 +1,72 @@ +//// [tests/cases/compiler/importAttributeMostSpecificType.ts] //// + +=== /bun-sqlite.d.ts === +declare module "databases/*.sqlite" with { type: "sqlite" } { +>"databases/*.sqlite" : typeof import("databases/*.sqlite") +>type : "sqlite" + + const database: { +>database : { storage: "external"; filename: string; } + + storage: "external"; +>storage : "external" + + filename: string; +>filename : string + + }; + export default database; +>database : { storage: "external"; filename: string; } +} + +declare module "*.sqlite" with { type: "sqlite", embed: "true" } { +>"*.sqlite" : typeof import("*.sqlite") +>type : "sqlite" +>embed : "true" + + const database: { +>database : { storage: "embedded"; contents: Uint8Array; } + + storage: "embedded"; +>storage : "embedded" + + contents: Uint8Array; +>contents : Uint8Array + + }; + export default database; +>database : { storage: "embedded"; contents: Uint8Array; } +} + +=== /index.ts === +import externalDatabase from "databases/app.sqlite" with { type: "sqlite" }; +>externalDatabase : { storage: "external"; filename: string; } +>type : error + +import embeddedDatabase from "databases/app.sqlite" with { type: "sqlite", embed: "true" }; +>embeddedDatabase : { storage: "embedded"; contents: Uint8Array; } +>type : error +>embed : error + +const expectedExternalStorage: "external" = externalDatabase.storage; +>expectedExternalStorage : "external" +>externalDatabase.storage : "external" +>externalDatabase : { storage: "external"; filename: string; } +>storage : "external" + +const expectedEmbeddedStorage: "embedded" = embeddedDatabase.storage; +>expectedEmbeddedStorage : "embedded" +>embeddedDatabase.storage : "embedded" +>embeddedDatabase : { storage: "embedded"; contents: Uint8Array; } +>storage : "embedded" + +externalDatabase.filename; +>externalDatabase.filename : string +>externalDatabase : { storage: "external"; filename: string; } +>filename : string + +embeddedDatabase.contents; +>embeddedDatabase.contents : Uint8Array +>embeddedDatabase : { storage: "embedded"; contents: Uint8Array; } +>contents : Uint8Array + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.errors.txt b/tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.errors.txt new file mode 100644 index 0000000000000..98cf0275d292b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.errors.txt @@ -0,0 +1,16 @@ +/types.d.ts(1,16): error TS1550: An ambient module declaration with import attributes must use a pattern name with an '*' character. + + +==== /types.d.ts (1 errors) ==== + declare module "plainstring" with { type: "css" } { + ~~~~~~~~~~~~~ +!!! error TS1550: An ambient module declaration with import attributes must use a pattern name with an '*' character. + export const value: "plain"; + } + +==== /index.ts (0 errors) ==== + import { value as withoutAttributes } from "plainstring"; + import { value as withAttributes } from "plainstring" with { type: "ignored" }; + + const first: "plain" = withoutAttributes; + const second: "plain" = withAttributes; \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.symbols b/tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.symbols new file mode 100644 index 0000000000000..6cae6aea9cb22 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.symbols @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/importAttributePlainStringAmbientModule.ts] //// + +=== /types.d.ts === +declare module "plainstring" with { type: "css" } { +>"plainstring" : Symbol("plainstring", Decl(types.d.ts, 0, 0)) +>type : Symbol(type, Decl(types.d.ts, 0, 35)) + + export const value: "plain"; +>value : Symbol(value, Decl(types.d.ts, 1, 16)) +} + +=== /index.ts === +import { value as withoutAttributes } from "plainstring"; +>value : Symbol(withoutAttributes, Decl(types.d.ts, 1, 16)) +>withoutAttributes : Symbol(withoutAttributes, Decl(index.ts, 0, 8)) + +import { value as withAttributes } from "plainstring" with { type: "ignored" }; +>value : Symbol(withoutAttributes, Decl(types.d.ts, 1, 16)) +>withAttributes : Symbol(withAttributes, Decl(index.ts, 1, 8)) + +const first: "plain" = withoutAttributes; +>first : Symbol(first, Decl(index.ts, 3, 5)) +>withoutAttributes : Symbol(withoutAttributes, Decl(index.ts, 0, 8)) + +const second: "plain" = withAttributes; +>second : Symbol(second, Decl(index.ts, 4, 5)) +>withAttributes : Symbol(withAttributes, Decl(index.ts, 1, 8)) + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.types b/tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.types new file mode 100644 index 0000000000000..e3a3853b8165a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributePlainStringAmbientModule.types @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/importAttributePlainStringAmbientModule.ts] //// + +=== /types.d.ts === +declare module "plainstring" with { type: "css" } { +>"plainstring" : typeof import("plainstring") +>type : "css" + + export const value: "plain"; +>value : "plain" +} + +=== /index.ts === +import { value as withoutAttributes } from "plainstring"; +>value : "plain" +>withoutAttributes : "plain" + +import { value as withAttributes } from "plainstring" with { type: "ignored" }; +>value : "plain" +>withAttributes : "plain" +>type : any + +const first: "plain" = withoutAttributes; +>first : "plain" +>withoutAttributes : "plain" + +const second: "plain" = withAttributes; +>second : "plain" +>withAttributes : "plain" + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeType1.errors.txt b/tsc/testdata/baselines/reference/compiler/importAttributeType1.errors.txt new file mode 100644 index 0000000000000..60b42d92e9f08 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeType1.errors.txt @@ -0,0 +1,55 @@ +/augmentation.ts(2,40): error TS1551: Import attributes are not allowed on a module augmentation. +/checkErrors.d.ts(1,37): error TS2322: Type '{ type: number; }' is not assignable to type 'ImportAttributes'. + Property 'type' is incompatible with index signature. + Type 'number' is not assignable to type 'string'. +/checkErrors.d.ts(2,37): error TS2322: Type '{ type: { name: string; }; }' is not assignable to type 'ImportAttributes'. + Property 'type' is incompatible with index signature. + Type '{ name: string; }' is not assignable to type 'string'. + + +==== /valid.d.ts (0 errors) ==== + declare module "*.asset" with { type: "css" } { + const stylesheet: CSSStyleSheet; + export default stylesheet; + } + + declare module "*.text" with { type: "text" } { + const text: string; + export default text; + } + + declare module "*.data" with { type: "json" | "json5" } { + const data: { version: number }; + export default data; + } + + declare module "*.augmentable" { + export interface Existing {} + } +==== /valid.ts (0 errors) ==== + import stylesheet from "./button.asset" with { type: "css" }; + import text from "./license.text" with { type: "text" }; + import data from "./config.data" with { type: "json5" }; + + stylesheet.insertRule(""); + text.toUpperCase(); + data.version.toFixed(); + +==== /checkErrors.d.ts (2 errors) ==== + declare module "*.numberValue" with { type: number } {} + ~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ type: number; }' is not assignable to type 'ImportAttributes'. +!!! error TS2322: Property 'type' is incompatible with index signature. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + declare module "*.objectValue" with { type: { name: string } } {} + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ type: { name: string; }; }' is not assignable to type 'ImportAttributes'. +!!! error TS2322: Property 'type' is incompatible with index signature. +!!! error TS2322: Type '{ name: string; }' is not assignable to type 'string'. +==== /augmentation.ts (1 errors) ==== + export {}; + declare module "file.augmentable" with { type: "css" } { + ~~~~~~~~~~~~~~~ +!!! error TS1551: Import attributes are not allowed on a module augmentation. + export interface Added {} + } \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeTypeOnlyImports.symbols b/tsc/testdata/baselines/reference/compiler/importAttributeTypeOnlyImports.symbols new file mode 100644 index 0000000000000..73bb06e31f013 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeTypeOnlyImports.symbols @@ -0,0 +1,104 @@ +//// [tests/cases/compiler/importAttributeTypeOnlyImports.ts] //// + +=== /types.d.ts === +declare module "*.style" with { type: "css" } { +>"*.style" : Symbol("*.style", Decl(types.d.ts, 0, 0)) +>type : Symbol(type, Decl(types.d.ts, 0, 31)) + + export interface Style { +>Style : Symbol(Style, Decl(types.d.ts, 0, 47)) + + kind: "css"; +>kind : Symbol(Style.kind, Decl(types.d.ts, 1, 28)) + } +} + +declare module "require/*.style" with { type: "css", "resolution-mode": "require" } { +>"require/*.style" : Symbol("require/*.style", Decl(types.d.ts, 4, 1)) +>type : Symbol(type, Decl(types.d.ts, 6, 39)) +>"resolution-mode" : Symbol("resolution-mode", Decl(types.d.ts, 6, 52)) + + export interface RequireStyle { +>RequireStyle : Symbol(RequireStyle, Decl(types.d.ts, 6, 85)) + + kind: "require-css"; +>kind : Symbol(RequireStyle.kind, Decl(types.d.ts, 7, 35)) + } +} + +=== /reexports.ts === +export type { Style } from "plain.style" with { type: "css" }; +>Style : Symbol(Style, Decl(reexports.ts, 0, 13)) + +export type { RequireStyle } from "require/reexport.style" with { type: "css", "resolution-mode": "require" }; +>RequireStyle : Symbol(RequireStyle, Decl(reexports.ts, 1, 13)) + +=== /jsdoc.js === +/** @import { Style } from "jsdoc.style" with { type: "css" } */ + +/** @type {Style} */ +const jsdocStyle = { kind: "css" }; +>jsdocStyle : Symbol(jsdocStyle, Decl(jsdoc.js, 3, 5)) +>kind : Symbol(kind, Decl(jsdoc.js, 3, 20)) + +const jsdocCssKind = jsdocStyle.kind; +>jsdocCssKind : Symbol(jsdocCssKind, Decl(jsdoc.js, 4, 5)) +>jsdocStyle.kind : Symbol(Style.kind, Decl(types.d.ts, 1, 28)) +>jsdocStyle : Symbol(jsdocStyle, Decl(jsdoc.js, 3, 5)) +>kind : Symbol(Style.kind, Decl(types.d.ts, 1, 28)) + +=== /index.ts === +import type { Style } from "plain.style" with { type: "css" }; +>Style : Symbol(Style, Decl(index.ts, 0, 13)) + +import type { RequireStyle } from "require/import.style" with { type: "css", "resolution-mode": "require" }; +>RequireStyle : Symbol(RequireStyle, Decl(index.ts, 1, 13)) + +type ImportTypeStyle = import("inline.style", { with: { type: "css" } }).Style; +>ImportTypeStyle : Symbol(ImportTypeStyle, Decl(index.ts, 1, 108)) +>Style : Symbol(Style, Decl(types.d.ts, 0, 47)) + +type ImportTypeRequireStyle = import("require/inline.style", { with: { type: "css", "resolution-mode": "require" } }).RequireStyle; +>ImportTypeRequireStyle : Symbol(ImportTypeRequireStyle, Decl(index.ts, 3, 79)) +>RequireStyle : Symbol(RequireStyle, Decl(types.d.ts, 6, 85)) + +declare const importedStyle: Style; +>importedStyle : Symbol(importedStyle, Decl(index.ts, 6, 13)) +>Style : Symbol(Style, Decl(index.ts, 0, 13)) + +declare const importedRequireStyle: RequireStyle; +>importedRequireStyle : Symbol(importedRequireStyle, Decl(index.ts, 7, 13)) +>RequireStyle : Symbol(RequireStyle, Decl(index.ts, 1, 13)) + +declare const importTypeStyle: ImportTypeStyle; +>importTypeStyle : Symbol(importTypeStyle, Decl(index.ts, 8, 13)) +>ImportTypeStyle : Symbol(ImportTypeStyle, Decl(index.ts, 1, 108)) + +declare const importTypeRequireStyle: ImportTypeRequireStyle; +>importTypeRequireStyle : Symbol(importTypeRequireStyle, Decl(index.ts, 9, 13)) +>ImportTypeRequireStyle : Symbol(ImportTypeRequireStyle, Decl(index.ts, 3, 79)) + +const cssKind: "css" = importedStyle.kind; +>cssKind : Symbol(cssKind, Decl(index.ts, 11, 5)) +>importedStyle.kind : Symbol(Style.kind, Decl(types.d.ts, 1, 28)) +>importedStyle : Symbol(importedStyle, Decl(index.ts, 6, 13)) +>kind : Symbol(Style.kind, Decl(types.d.ts, 1, 28)) + +const requireCssKind: "require-css" = importedRequireStyle.kind; +>requireCssKind : Symbol(requireCssKind, Decl(index.ts, 12, 5)) +>importedRequireStyle.kind : Symbol(RequireStyle.kind, Decl(types.d.ts, 7, 35)) +>importedRequireStyle : Symbol(importedRequireStyle, Decl(index.ts, 7, 13)) +>kind : Symbol(RequireStyle.kind, Decl(types.d.ts, 7, 35)) + +const importTypeCssKind: "css" = importTypeStyle.kind; +>importTypeCssKind : Symbol(importTypeCssKind, Decl(index.ts, 13, 5)) +>importTypeStyle.kind : Symbol(Style.kind, Decl(types.d.ts, 1, 28)) +>importTypeStyle : Symbol(importTypeStyle, Decl(index.ts, 8, 13)) +>kind : Symbol(Style.kind, Decl(types.d.ts, 1, 28)) + +const importTypeRequireCssKind: "require-css" = importTypeRequireStyle.kind; +>importTypeRequireCssKind : Symbol(importTypeRequireCssKind, Decl(index.ts, 14, 5)) +>importTypeRequireStyle.kind : Symbol(RequireStyle.kind, Decl(types.d.ts, 7, 35)) +>importTypeRequireStyle : Symbol(importTypeRequireStyle, Decl(index.ts, 9, 13)) +>kind : Symbol(RequireStyle.kind, Decl(types.d.ts, 7, 35)) + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeTypeOnlyImports.types b/tsc/testdata/baselines/reference/compiler/importAttributeTypeOnlyImports.types new file mode 100644 index 0000000000000..813292fbb46f9 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeTypeOnlyImports.types @@ -0,0 +1,102 @@ +//// [tests/cases/compiler/importAttributeTypeOnlyImports.ts] //// + +=== /types.d.ts === +declare module "*.style" with { type: "css" } { +>"*.style" : typeof import("*.style") +>type : "css" + + export interface Style { + kind: "css"; +>kind : "css" + } +} + +declare module "require/*.style" with { type: "css", "resolution-mode": "require" } { +>"require/*.style" : typeof import("require/*.style") +>type : "css" +>"resolution-mode" : "require" + + export interface RequireStyle { + kind: "require-css"; +>kind : "require-css" + } +} + +=== /reexports.ts === +export type { Style } from "plain.style" with { type: "css" }; +>Style : Style +>type : error + +export type { RequireStyle } from "require/reexport.style" with { type: "css", "resolution-mode": "require" }; +>RequireStyle : import("require/*.style").RequireStyle +>type : error + +=== /jsdoc.js === +/** @import { Style } from "jsdoc.style" with { type: "css" } */ + +/** @type {Style} */ +const jsdocStyle = { kind: "css" }; +>jsdocStyle : Style +>{ kind: "css" } : { kind: "css"; } +>kind : "css" +>"css" : "css" + +const jsdocCssKind = jsdocStyle.kind; +>jsdocCssKind : "css" +>jsdocStyle.kind : "css" +>jsdocStyle : Style +>kind : "css" + +=== /index.ts === +import type { Style } from "plain.style" with { type: "css" }; +>Style : Style +>type : error + +import type { RequireStyle } from "require/import.style" with { type: "css", "resolution-mode": "require" }; +>RequireStyle : RequireStyle +>type : error + +type ImportTypeStyle = import("inline.style", { with: { type: "css" } }).Style; +>ImportTypeStyle : Style +>type : error + +type ImportTypeRequireStyle = import("require/inline.style", { with: { type: "css", "resolution-mode": "require" } }).RequireStyle; +>ImportTypeRequireStyle : RequireStyle +>type : error + +declare const importedStyle: Style; +>importedStyle : Style + +declare const importedRequireStyle: RequireStyle; +>importedRequireStyle : RequireStyle + +declare const importTypeStyle: ImportTypeStyle; +>importTypeStyle : Style + +declare const importTypeRequireStyle: ImportTypeRequireStyle; +>importTypeRequireStyle : RequireStyle + +const cssKind: "css" = importedStyle.kind; +>cssKind : "css" +>importedStyle.kind : "css" +>importedStyle : Style +>kind : "css" + +const requireCssKind: "require-css" = importedRequireStyle.kind; +>requireCssKind : "require-css" +>importedRequireStyle.kind : "require-css" +>importedRequireStyle : RequireStyle +>kind : "require-css" + +const importTypeCssKind: "css" = importTypeStyle.kind; +>importTypeCssKind : "css" +>importTypeStyle.kind : "css" +>importTypeStyle : Style +>kind : "css" + +const importTypeRequireCssKind: "require-css" = importTypeRequireStyle.kind; +>importTypeRequireCssKind : "require-css" +>importTypeRequireStyle.kind : "require-css" +>importTypeRequireStyle : RequireStyle +>kind : "require-css" + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.js b/tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.js new file mode 100644 index 0000000000000..d3938e17aad5e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.js @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/importAttributesDeclarationEmit.ts] //// + +//// [types.d.ts] +declare module "*.style" with { type: "css" } { + export interface Style { + kind: "css"; + } +} + +declare module "formatted/*.style" with { type: "css", format: "module" } { + export interface FormattedStyle { + kind: "css-module"; + } +} + +//// [index.ts] +import type { Style } from "plain.style" with { type: "css" }; +import type { FormattedStyle } from "formatted/import.style" with { type: "css", format: "module" }; + +export interface LocalStyle extends Style {} +export interface LocalFormattedStyle extends FormattedStyle {} + +export type { Style } from "reexport.style" with { type: "css" }; +export type { FormattedStyle } from "formatted/reexport.style" with { type: "css", format: "module" }; + +export type InlineStyle = import("inline.style", { with: { type: "css" } }).Style; +export type InlineFormattedStyle = import("formatted/inline.style", { with: { type: "css", format: "module" } }).FormattedStyle; + + + +//// [index.d.ts] +import type { Style } from "plain.style" with { type: "css" }; +import type { FormattedStyle } from "formatted/import.style" with { type: "css", format: "module" }; +export interface LocalStyle extends Style { +} +export interface LocalFormattedStyle extends FormattedStyle { +} +export type { Style } from "reexport.style" with { type: "css" }; +export type { FormattedStyle } from "formatted/reexport.style" with { type: "css", format: "module" }; +export type InlineStyle = import("inline.style", { with: { type: "css" } }).Style; +export type InlineFormattedStyle = import("formatted/inline.style", { with: { type: "css", format: "module" } }).FormattedStyle; diff --git a/tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.symbols b/tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.symbols new file mode 100644 index 0000000000000..5f4a8802d9d2d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.symbols @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/importAttributesDeclarationEmit.ts] //// + +=== /types.d.ts === +declare module "*.style" with { type: "css" } { +>"*.style" : Symbol("*.style", Decl(types.d.ts, 0, 0)) +>type : Symbol(type, Decl(types.d.ts, 0, 31)) + + export interface Style { +>Style : Symbol(Style, Decl(types.d.ts, 0, 47)) + + kind: "css"; +>kind : Symbol(Style.kind, Decl(types.d.ts, 1, 28)) + } +} + +declare module "formatted/*.style" with { type: "css", format: "module" } { +>"formatted/*.style" : Symbol("formatted/*.style", Decl(types.d.ts, 4, 1)) +>type : Symbol(type, Decl(types.d.ts, 6, 41)) +>format : Symbol(format, Decl(types.d.ts, 6, 54)) + + export interface FormattedStyle { +>FormattedStyle : Symbol(FormattedStyle, Decl(types.d.ts, 6, 75)) + + kind: "css-module"; +>kind : Symbol(FormattedStyle.kind, Decl(types.d.ts, 7, 37)) + } +} + +=== /index.ts === +import type { Style } from "plain.style" with { type: "css" }; +>Style : Symbol(Style, Decl(index.ts, 0, 13)) + +import type { FormattedStyle } from "formatted/import.style" with { type: "css", format: "module" }; +>FormattedStyle : Symbol(FormattedStyle, Decl(index.ts, 1, 13)) + +export interface LocalStyle extends Style {} +>LocalStyle : Symbol(LocalStyle, Decl(index.ts, 1, 100)) +>Style : Symbol(Style, Decl(index.ts, 0, 13)) + +export interface LocalFormattedStyle extends FormattedStyle {} +>LocalFormattedStyle : Symbol(LocalFormattedStyle, Decl(index.ts, 3, 44)) +>FormattedStyle : Symbol(FormattedStyle, Decl(index.ts, 1, 13)) + +export type { Style } from "reexport.style" with { type: "css" }; +>Style : Symbol(Style, Decl(index.ts, 6, 13)) + +export type { FormattedStyle } from "formatted/reexport.style" with { type: "css", format: "module" }; +>FormattedStyle : Symbol(FormattedStyle, Decl(index.ts, 7, 13)) + +export type InlineStyle = import("inline.style", { with: { type: "css" } }).Style; +>InlineStyle : Symbol(InlineStyle, Decl(index.ts, 7, 102)) +>Style : Symbol(Style, Decl(types.d.ts, 0, 47)) + +export type InlineFormattedStyle = import("formatted/inline.style", { with: { type: "css", format: "module" } }).FormattedStyle; +>InlineFormattedStyle : Symbol(InlineFormattedStyle, Decl(index.ts, 9, 82)) +>FormattedStyle : Symbol(FormattedStyle, Decl(types.d.ts, 6, 75)) + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.types b/tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.types new file mode 100644 index 0000000000000..80ddae36cbce6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributesDeclarationEmit.types @@ -0,0 +1,55 @@ +//// [tests/cases/compiler/importAttributesDeclarationEmit.ts] //// + +=== /types.d.ts === +declare module "*.style" with { type: "css" } { +>"*.style" : typeof import("*.style") +>type : "css" + + export interface Style { + kind: "css"; +>kind : "css" + } +} + +declare module "formatted/*.style" with { type: "css", format: "module" } { +>"formatted/*.style" : typeof import("formatted/*.style") +>type : "css" +>format : "module" + + export interface FormattedStyle { + kind: "css-module"; +>kind : "css-module" + } +} + +=== /index.ts === +import type { Style } from "plain.style" with { type: "css" }; +>Style : Style +>type : error + +import type { FormattedStyle } from "formatted/import.style" with { type: "css", format: "module" }; +>FormattedStyle : FormattedStyle +>type : error +>format : error + +export interface LocalStyle extends Style {} +export interface LocalFormattedStyle extends FormattedStyle {} + +export type { Style } from "reexport.style" with { type: "css" }; +>Style : Style +>type : error + +export type { FormattedStyle } from "formatted/reexport.style" with { type: "css", format: "module" }; +>FormattedStyle : FormattedStyle +>type : error +>format : error + +export type InlineStyle = import("inline.style", { with: { type: "css" } }).Style; +>InlineStyle : Style +>type : error + +export type InlineFormattedStyle = import("formatted/inline.style", { with: { type: "css", format: "module" } }).FormattedStyle; +>InlineFormattedStyle : FormattedStyle +>type : error +>format : error + diff --git a/tsc/testdata/baselines/reference/compiler/parseAssertEntriesError.types b/tsc/testdata/baselines/reference/compiler/parseAssertEntriesError.types index 4b543381a22f7..fe3eb63a7893e 100644 --- a/tsc/testdata/baselines/reference/compiler/parseAssertEntriesError.types +++ b/tsc/testdata/baselines/reference/compiler/parseAssertEntriesError.types @@ -16,12 +16,12 @@ export type LocalInterface = >import("pkg", { with: {1234, "resolution-mode": "import"} }).ImportInterface : any >import("pkg", { with: {1234, "resolution-mode": "import"} }) : Promise<{ default: typeof import("./node_modules/pkg/import"); }> >"pkg" : "pkg" ->{ with: {1234, "resolution-mode": "import"} } : { with: { 1234: any; "resolution-mode": string; }; } ->with : { 1234: any; "resolution-mode": string; } ->{1234, "resolution-mode": "import"} : { 1234: any; "resolution-mode": string; } +>{ with: {1234, "resolution-mode": "import"} } : { with: { readonly 1234: any; readonly "resolution-mode": "import"; }; } +>with : { readonly 1234: any; readonly "resolution-mode": "import"; } +>{1234, "resolution-mode": "import"} : { readonly 1234: any; readonly "resolution-mode": "import"; } >1234 : any > : any ->"resolution-mode" : string +>"resolution-mode" : "import" >"import" : "import" >ImportInterface : any diff --git a/tsc/testdata/baselines/reference/compiler/parseImportAttributesError.types b/tsc/testdata/baselines/reference/compiler/parseImportAttributesError.types index 6922d4224ca16..29b4de4fbca27 100644 --- a/tsc/testdata/baselines/reference/compiler/parseImportAttributesError.types +++ b/tsc/testdata/baselines/reference/compiler/parseImportAttributesError.types @@ -16,12 +16,12 @@ export type LocalInterface = >import("pkg", { with: {1234, "resolution-mode": "import"} }).ImportInterface : any >import("pkg", { with: {1234, "resolution-mode": "import"} }) : Promise<{ default: typeof import("./node_modules/pkg/import"); }> >"pkg" : "pkg" ->{ with: {1234, "resolution-mode": "import"} } : { with: { 1234: any; "resolution-mode": string; }; } ->with : { 1234: any; "resolution-mode": string; } ->{1234, "resolution-mode": "import"} : { 1234: any; "resolution-mode": string; } +>{ with: {1234, "resolution-mode": "import"} } : { with: { readonly 1234: any; readonly "resolution-mode": "import"; }; } +>with : { readonly 1234: any; readonly "resolution-mode": "import"; } +>{1234, "resolution-mode": "import"} : { readonly 1234: any; readonly "resolution-mode": "import"; } >1234 : any > : any ->"resolution-mode" : string +>"resolution-mode" : "import" >"import" : "import" >ImportInterface : any diff --git a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.errors.txt b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.errors.txt new file mode 100644 index 0000000000000..c4990fd307206 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.errors.txt @@ -0,0 +1,32 @@ +/index.ts(9,7): error TS2339: Property 'augmented' does not exist on type 'typeof import("*.asset")'. + + +==== /a.d.ts (0 errors) ==== + declare module "*.asset" { + export const fromA: "a"; + } + +==== /b.d.ts (0 errors) ==== + declare module "*.asset" { + export const fromB: "b"; + } + +==== /augmentation.ts (0 errors) ==== + export {}; + + declare module "augmented.asset" { + export const augmented: "augmented"; + } + +==== /index.ts (1 errors) ==== + import * as augmented from "augmented.asset"; + augmented.fromA; + augmented.fromB; + augmented.augmented; + + import * as other from "other.asset"; + other.fromA; + other.fromB; + other.augmented; + ~~~~~~~~~ +!!! error TS2339: Property 'augmented' does not exist on type 'typeof import("*.asset")'. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.symbols b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.symbols new file mode 100644 index 0000000000000..33d49a0392ee6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.symbols @@ -0,0 +1,63 @@ +//// [tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts] //// + +=== /a.d.ts === +declare module "*.asset" { +>"*.asset" : Symbol("*.asset", Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0)) + + export const fromA: "a"; +>fromA : Symbol(fromA, Decl(a.d.ts, 1, 16)) +} + +=== /b.d.ts === +declare module "*.asset" { +>"*.asset" : Symbol("*.asset", Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0)) + + export const fromB: "b"; +>fromB : Symbol(fromB, Decl(b.d.ts, 1, 16)) +} + +=== /augmentation.ts === +export {}; + +declare module "augmented.asset" { +>"augmented.asset" : Symbol("augmented.asset", Decl(augmentation.ts, 0, 10), Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0)) + + export const augmented: "augmented"; +>augmented : Symbol(augmented, Decl(augmentation.ts, 3, 16)) +} + +=== /index.ts === +import * as augmented from "augmented.asset"; +>augmented : Symbol(augmented, Decl(index.ts, 0, 6)) + +augmented.fromA; +>augmented.fromA : Symbol(augmented.fromA, Decl(a.d.ts, 1, 16)) +>augmented : Symbol(augmented, Decl(index.ts, 0, 6)) +>fromA : Symbol(augmented.fromA, Decl(a.d.ts, 1, 16)) + +augmented.fromB; +>augmented.fromB : Symbol(augmented.fromB, Decl(b.d.ts, 1, 16)) +>augmented : Symbol(augmented, Decl(index.ts, 0, 6)) +>fromB : Symbol(augmented.fromB, Decl(b.d.ts, 1, 16)) + +augmented.augmented; +>augmented.augmented : Symbol(augmented.augmented, Decl(augmentation.ts, 3, 16)) +>augmented : Symbol(augmented, Decl(index.ts, 0, 6)) +>augmented : Symbol(augmented.augmented, Decl(augmentation.ts, 3, 16)) + +import * as other from "other.asset"; +>other : Symbol(other, Decl(index.ts, 5, 6)) + +other.fromA; +>other.fromA : Symbol(augmented.fromA, Decl(a.d.ts, 1, 16)) +>other : Symbol(other, Decl(index.ts, 5, 6)) +>fromA : Symbol(augmented.fromA, Decl(a.d.ts, 1, 16)) + +other.fromB; +>other.fromB : Symbol(augmented.fromB, Decl(b.d.ts, 1, 16)) +>other : Symbol(other, Decl(index.ts, 5, 6)) +>fromB : Symbol(augmented.fromB, Decl(b.d.ts, 1, 16)) + +other.augmented; +>other : Symbol(other, Decl(index.ts, 5, 6)) + diff --git a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.types b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.types new file mode 100644 index 0000000000000..5be3b271f0dca --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.types @@ -0,0 +1,65 @@ +//// [tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts] //// + +=== /a.d.ts === +declare module "*.asset" { +>"*.asset" : typeof import("*.asset") + + export const fromA: "a"; +>fromA : "a" +} + +=== /b.d.ts === +declare module "*.asset" { +>"*.asset" : typeof import("*.asset") + + export const fromB: "b"; +>fromB : "b" +} + +=== /augmentation.ts === +export {}; + +declare module "augmented.asset" { +>"augmented.asset" : typeof import("augmented.asset") + + export const augmented: "augmented"; +>augmented : "augmented" +} + +=== /index.ts === +import * as augmented from "augmented.asset"; +>augmented : typeof augmented + +augmented.fromA; +>augmented.fromA : "a" +>augmented : typeof augmented +>fromA : "a" + +augmented.fromB; +>augmented.fromB : "b" +>augmented : typeof augmented +>fromB : "b" + +augmented.augmented; +>augmented.augmented : "augmented" +>augmented : typeof augmented +>augmented : "augmented" + +import * as other from "other.asset"; +>other : typeof other + +other.fromA; +>other.fromA : "a" +>other : typeof other +>fromA : "a" + +other.fromB; +>other.fromB : "b" +>other : typeof other +>fromB : "b" + +other.augmented; +>other.augmented : any +>other : typeof other +>augmented : any + diff --git a/tsc/testdata/baselines/reference/compiler/resolutionModeOverrideWithOtherAttributes.symbols b/tsc/testdata/baselines/reference/compiler/resolutionModeOverrideWithOtherAttributes.symbols new file mode 100644 index 0000000000000..c5cf82c151341 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/resolutionModeOverrideWithOtherAttributes.symbols @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/resolutionModeOverrideWithOtherAttributes.ts] //// + +=== /node_modules/pkg/index.d.mts === +export declare const value: "import"; +>value : Symbol(value, Decl(index.d.mts, 0, 20)) + +=== /node_modules/pkg/index.d.cts === +export declare const value: "require"; +>value : Symbol(value, Decl(index.d.cts, 0, 20)) + +=== /app.ts === +import type { value } from "pkg" with { type: "typescript", "resolution-mode": "require" }; +>value : Symbol(value, Decl(app.ts, 0, 13)) + +declare const expected: "require"; +>expected : Symbol(expected, Decl(app.ts, 2, 13)) + +const actual: typeof value = expected; +>actual : Symbol(actual, Decl(app.ts, 3, 5)) +>value : Symbol(value, Decl(app.ts, 0, 13)) +>expected : Symbol(expected, Decl(app.ts, 2, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/resolutionModeOverrideWithOtherAttributes.types b/tsc/testdata/baselines/reference/compiler/resolutionModeOverrideWithOtherAttributes.types new file mode 100644 index 0000000000000..31062ebe42653 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/resolutionModeOverrideWithOtherAttributes.types @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/resolutionModeOverrideWithOtherAttributes.ts] //// + +=== /node_modules/pkg/index.d.mts === +export declare const value: "import"; +>value : "import" + +=== /node_modules/pkg/index.d.cts === +export declare const value: "require"; +>value : "require" + +=== /app.ts === +import type { value } from "pkg" with { type: "typescript", "resolution-mode": "require" }; +>value : any +>type : error + +declare const expected: "require"; +>expected : "require" + +const actual: typeof value = expected; +>actual : "require" +>value : "require" +>expected : "require" + diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=commonjs).js b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=commonjs).js index 4bac8112f2063..a683728c3d78d 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=commonjs).js +++ b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=commonjs).js @@ -143,7 +143,7 @@ const h = Promise.resolve().then(() => __importStar(require('./0'))); export declare const a = 1; export declare const b = 2; //// [1.d.ts] -import './0'; +import './0' with { type: "json" }; //// [2.d.ts] export {}; //// [3.d.ts] diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=commonjs).types b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=commonjs).types index e642e0263aa16..67d5ecc6fb69a 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=commonjs).types +++ b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=commonjs).types @@ -73,22 +73,22 @@ const b = import('./0', { with: { type: "json" } }) >b : Promise >import('./0', { with: { type: "json" } }) : Promise >'./0' : "./0" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" const c = import('./0', { with: { type: "json", ttype: "typo" } }) >c : Promise >import('./0', { with: { type: "json", ttype: "typo" } }) : Promise >'./0' : "./0" ->{ with: { type: "json", ttype: "typo" } } : { with: { type: string; ttype: string; }; } ->with : { type: string; ttype: string; } ->{ type: "json", ttype: "typo" } : { type: string; ttype: string; } ->type : string +>{ with: { type: "json", ttype: "typo" } } : { with: { readonly type: "json"; readonly ttype: "typo"; }; } +>with : { readonly type: "json"; readonly ttype: "typo"; } +>{ type: "json", ttype: "typo" } : { readonly type: "json"; readonly ttype: "typo"; } +>type : "json" >"json" : "json" ->ttype : string +>ttype : "typo" >"typo" : "typo" const d = import('./0', { with: {} }) @@ -130,10 +130,10 @@ const h = import('./0', { with: { type: "json" }},) >h : Promise >import('./0', { with: { type: "json" }},) : Promise >'./0' : "./0" ->{ with: { type: "json" }} : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" }} : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=es2015).js b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=es2015).js index 6f817a8b24276..02a19195156d5 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=es2015).js +++ b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=es2015).js @@ -70,7 +70,7 @@ const h = import('./0', { with: { type: "json" } }); export declare const a = 1; export declare const b = 2; //// [1.d.ts] -import './0'; +import './0' with { type: "json" }; //// [2.d.ts] export {}; //// [3.d.ts] diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=es2015).types b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=es2015).types index e642e0263aa16..67d5ecc6fb69a 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=es2015).types +++ b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=es2015).types @@ -73,22 +73,22 @@ const b = import('./0', { with: { type: "json" } }) >b : Promise >import('./0', { with: { type: "json" } }) : Promise >'./0' : "./0" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" const c = import('./0', { with: { type: "json", ttype: "typo" } }) >c : Promise >import('./0', { with: { type: "json", ttype: "typo" } }) : Promise >'./0' : "./0" ->{ with: { type: "json", ttype: "typo" } } : { with: { type: string; ttype: string; }; } ->with : { type: string; ttype: string; } ->{ type: "json", ttype: "typo" } : { type: string; ttype: string; } ->type : string +>{ with: { type: "json", ttype: "typo" } } : { with: { readonly type: "json"; readonly ttype: "typo"; }; } +>with : { readonly type: "json"; readonly ttype: "typo"; } +>{ type: "json", ttype: "typo" } : { readonly type: "json"; readonly ttype: "typo"; } +>type : "json" >"json" : "json" ->ttype : string +>ttype : "typo" >"typo" : "typo" const d = import('./0', { with: {} }) @@ -130,10 +130,10 @@ const h = import('./0', { with: { type: "json" }},) >h : Promise >import('./0', { with: { type: "json" }},) : Promise >'./0' : "./0" ->{ with: { type: "json" }} : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" }} : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=esnext).js b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=esnext).js index 6f817a8b24276..02a19195156d5 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=esnext).js +++ b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=esnext).js @@ -70,7 +70,7 @@ const h = import('./0', { with: { type: "json" } }); export declare const a = 1; export declare const b = 2; //// [1.d.ts] -import './0'; +import './0' with { type: "json" }; //// [2.d.ts] export {}; //// [3.d.ts] diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=esnext).types b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=esnext).types index e642e0263aa16..67d5ecc6fb69a 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion1(module=esnext).types +++ b/tsc/testdata/baselines/reference/conformance/importAssertion1(module=esnext).types @@ -73,22 +73,22 @@ const b = import('./0', { with: { type: "json" } }) >b : Promise >import('./0', { with: { type: "json" } }) : Promise >'./0' : "./0" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" const c = import('./0', { with: { type: "json", ttype: "typo" } }) >c : Promise >import('./0', { with: { type: "json", ttype: "typo" } }) : Promise >'./0' : "./0" ->{ with: { type: "json", ttype: "typo" } } : { with: { type: string; ttype: string; }; } ->with : { type: string; ttype: string; } ->{ type: "json", ttype: "typo" } : { type: string; ttype: string; } ->type : string +>{ with: { type: "json", ttype: "typo" } } : { with: { readonly type: "json"; readonly ttype: "typo"; }; } +>with : { readonly type: "json"; readonly ttype: "typo"; } +>{ type: "json", ttype: "typo" } : { readonly type: "json"; readonly ttype: "typo"; } +>type : "json" >"json" : "json" ->ttype : string +>ttype : "typo" >"typo" : "typo" const d = import('./0', { with: {} }) @@ -130,10 +130,10 @@ const h = import('./0', { with: { type: "json" }},) >h : Promise >import('./0', { with: { type: "json" }},) : Promise >'./0' : "./0" ->{ with: { type: "json" }} : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" }} : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion2(module=commonjs).js b/tsc/testdata/baselines/reference/conformance/importAssertion2(module=commonjs).js index fc784a987ea30..947aea50dd696 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion2(module=commonjs).js +++ b/tsc/testdata/baselines/reference/conformance/importAssertion2(module=commonjs).js @@ -82,10 +82,10 @@ Object.defineProperty(exports, "d", { enumerable: true, get: function () { retur export declare const a = 1; export declare const b = 2; //// [1.d.ts] -export {} from './0'; -export { a, b } from './0'; -export * from './0'; -export * as ns from './0'; +export {} from './0' with { type: "json" }; +export { a, b } from './0' with { type: "json" }; +export * from './0' with { type: "json" }; +export * as ns from './0' with { type: "json" }; //// [2.d.ts] -export { a, b } from './0'; -export { a as c, b as d } from './0'; +export { a, b } from './0' with {}; +export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion2(module=es2015).js b/tsc/testdata/baselines/reference/conformance/importAssertion2(module=es2015).js index 25a70583d401b..76487b3a9e94a 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion2(module=es2015).js +++ b/tsc/testdata/baselines/reference/conformance/importAssertion2(module=es2015).js @@ -32,10 +32,10 @@ export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; export declare const a = 1; export declare const b = 2; //// [1.d.ts] -export {} from './0'; -export { a, b } from './0'; -export * from './0'; -export * as ns from './0'; +export {} from './0' with { type: "json" }; +export { a, b } from './0' with { type: "json" }; +export * from './0' with { type: "json" }; +export * as ns from './0' with { type: "json" }; //// [2.d.ts] -export { a, b } from './0'; -export { a as c, b as d } from './0'; +export { a, b } from './0' with {}; +export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion2(module=esnext).js b/tsc/testdata/baselines/reference/conformance/importAssertion2(module=esnext).js index 4ab9dd3751d70..24f5c62b84812 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion2(module=esnext).js +++ b/tsc/testdata/baselines/reference/conformance/importAssertion2(module=esnext).js @@ -31,10 +31,10 @@ export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; export declare const a = 1; export declare const b = 2; //// [1.d.ts] -export {} from './0'; -export { a, b } from './0'; -export * from './0'; -export * as ns from './0'; +export {} from './0' with { type: "json" }; +export { a, b } from './0' with { type: "json" }; +export * from './0' with { type: "json" }; +export * as ns from './0' with { type: "json" }; //// [2.d.ts] -export { a, b } from './0'; -export { a as c, b as d } from './0'; +export { a, b } from './0' with {}; +export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).errors.txt b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).errors.txt deleted file mode 100644 index e1b1bba3d4679..0000000000000 --- a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).errors.txt +++ /dev/null @@ -1,26 +0,0 @@ -1.ts(1,27): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -1.ts(2,30): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -2.ts(1,31): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -2.ts(2,33): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - - -==== 0.ts (0 errors) ==== - export interface I { } - -==== 1.ts (2 errors) ==== - export type {} from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - export type { I } from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - -==== 2.ts (2 errors) ==== - import type { I } from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - import type * as foo from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).js b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).js index 01234b6f15d63..c862203ca26da 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).js +++ b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).js @@ -25,7 +25,7 @@ export {}; export interface I { } //// [1.d.ts] -export type {} from './0'; -export type { I } from './0'; +export type {} from './0' with { type: "json" }; +export type { I } from './0' with { type: "json" }; //// [2.d.ts] export {}; diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).types b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).types index f596ef955a214..c20a2dbd3a9bf 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).types +++ b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=es2015).types @@ -6,19 +6,19 @@ export interface I { } === 1.ts === export type {} from './0' with { type: "json" } ->type : any +>type : error export type { I } from './0' with { type: "json" } >I : import("./0").I ->type : any +>type : error === 2.ts === import type { I } from './0' with { type: "json" } >I : I ->type : any +>type : error import type * as foo from './0' with { type: "json" } >foo : typeof foo ->type : any +>type : error diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).errors.txt b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).errors.txt deleted file mode 100644 index 2f05b5fbb90fe..0000000000000 --- a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).errors.txt +++ /dev/null @@ -1,26 +0,0 @@ -1.ts(1,27): error TS2857: Import attributes cannot be used with type-only imports or exports. -1.ts(2,30): error TS2857: Import attributes cannot be used with type-only imports or exports. -2.ts(1,31): error TS2857: Import attributes cannot be used with type-only imports or exports. -2.ts(2,33): error TS2857: Import attributes cannot be used with type-only imports or exports. - - -==== 0.ts (0 errors) ==== - export interface I { } - -==== 1.ts (2 errors) ==== - export type {} from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - export type { I } from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - -==== 2.ts (2 errors) ==== - import type { I } from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - import type * as foo from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).js b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).js index 01234b6f15d63..c862203ca26da 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).js +++ b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).js @@ -25,7 +25,7 @@ export {}; export interface I { } //// [1.d.ts] -export type {} from './0'; -export type { I } from './0'; +export type {} from './0' with { type: "json" }; +export type { I } from './0' with { type: "json" }; //// [2.d.ts] export {}; diff --git a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).types b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).types index f596ef955a214..c20a2dbd3a9bf 100644 --- a/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).types +++ b/tsc/testdata/baselines/reference/conformance/importAssertion3(module=esnext).types @@ -6,19 +6,19 @@ export interface I { } === 1.ts === export type {} from './0' with { type: "json" } ->type : any +>type : error export type { I } from './0' with { type: "json" } >I : import("./0").I ->type : any +>type : error === 2.ts === import type { I } from './0' with { type: "json" } >I : I ->type : any +>type : error import type * as foo from './0' with { type: "json" } >foo : typeof foo ->type : any +>type : error diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=commonjs).js b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=commonjs).js index 948e874b7f684..5d88859b7ddd3 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=commonjs).js +++ b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=commonjs).js @@ -140,7 +140,7 @@ const h = Promise.resolve().then(() => __importStar(require('./0'))); export declare const a = 1; export declare const b = 2; //// [1.d.ts] -import './0'; +import './0' with { type: "json" }; //// [2.d.ts] export {}; //// [3.d.ts] diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=commonjs).types b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=commonjs).types index d752bedca219e..b11b1b88ce445 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=commonjs).types +++ b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=commonjs).types @@ -73,22 +73,22 @@ const b = import('./0', { with: { type: "json" } }) >b : Promise >import('./0', { with: { type: "json" } }) : Promise >'./0' : "./0" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" const c = import('./0', { with: { type: "json", ttype: "typo" } }) >c : Promise >import('./0', { with: { type: "json", ttype: "typo" } }) : Promise >'./0' : "./0" ->{ with: { type: "json", ttype: "typo" } } : { with: { type: string; ttype: string; }; } ->with : { type: string; ttype: string; } ->{ type: "json", ttype: "typo" } : { type: string; ttype: string; } ->type : string +>{ with: { type: "json", ttype: "typo" } } : { with: { readonly type: "json"; readonly ttype: "typo"; }; } +>with : { readonly type: "json"; readonly ttype: "typo"; } +>{ type: "json", ttype: "typo" } : { readonly type: "json"; readonly ttype: "typo"; } +>type : "json" >"json" : "json" ->ttype : string +>ttype : "typo" >"typo" : "typo" const d = import('./0', { with: {} }) @@ -130,9 +130,9 @@ const h = import('./0', { with: { type: "json" }},) >h : Promise >import('./0', { with: { type: "json" }},) : Promise >'./0' : "./0" ->{ with: { type: "json" }} : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" }} : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=es2015).js b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=es2015).js index a255708de517c..49883311f4e84 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=es2015).js +++ b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=es2015).js @@ -67,7 +67,7 @@ const h = import('./0', { with: { type: "json" } }); export declare const a = 1; export declare const b = 2; //// [1.d.ts] -import './0'; +import './0' with { type: "json" }; //// [2.d.ts] export {}; //// [3.d.ts] diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=es2015).types b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=es2015).types index d752bedca219e..b11b1b88ce445 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=es2015).types +++ b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=es2015).types @@ -73,22 +73,22 @@ const b = import('./0', { with: { type: "json" } }) >b : Promise >import('./0', { with: { type: "json" } }) : Promise >'./0' : "./0" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" const c = import('./0', { with: { type: "json", ttype: "typo" } }) >c : Promise >import('./0', { with: { type: "json", ttype: "typo" } }) : Promise >'./0' : "./0" ->{ with: { type: "json", ttype: "typo" } } : { with: { type: string; ttype: string; }; } ->with : { type: string; ttype: string; } ->{ type: "json", ttype: "typo" } : { type: string; ttype: string; } ->type : string +>{ with: { type: "json", ttype: "typo" } } : { with: { readonly type: "json"; readonly ttype: "typo"; }; } +>with : { readonly type: "json"; readonly ttype: "typo"; } +>{ type: "json", ttype: "typo" } : { readonly type: "json"; readonly ttype: "typo"; } +>type : "json" >"json" : "json" ->ttype : string +>ttype : "typo" >"typo" : "typo" const d = import('./0', { with: {} }) @@ -130,9 +130,9 @@ const h = import('./0', { with: { type: "json" }},) >h : Promise >import('./0', { with: { type: "json" }},) : Promise >'./0' : "./0" ->{ with: { type: "json" }} : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" }} : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=esnext).js b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=esnext).js index a255708de517c..49883311f4e84 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=esnext).js +++ b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=esnext).js @@ -67,7 +67,7 @@ const h = import('./0', { with: { type: "json" } }); export declare const a = 1; export declare const b = 2; //// [1.d.ts] -import './0'; +import './0' with { type: "json" }; //// [2.d.ts] export {}; //// [3.d.ts] diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=esnext).types b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=esnext).types index d752bedca219e..b11b1b88ce445 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes1(module=esnext).types +++ b/tsc/testdata/baselines/reference/conformance/importAttributes1(module=esnext).types @@ -73,22 +73,22 @@ const b = import('./0', { with: { type: "json" } }) >b : Promise >import('./0', { with: { type: "json" } }) : Promise >'./0' : "./0" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" const c = import('./0', { with: { type: "json", ttype: "typo" } }) >c : Promise >import('./0', { with: { type: "json", ttype: "typo" } }) : Promise >'./0' : "./0" ->{ with: { type: "json", ttype: "typo" } } : { with: { type: string; ttype: string; }; } ->with : { type: string; ttype: string; } ->{ type: "json", ttype: "typo" } : { type: string; ttype: string; } ->type : string +>{ with: { type: "json", ttype: "typo" } } : { with: { readonly type: "json"; readonly ttype: "typo"; }; } +>with : { readonly type: "json"; readonly ttype: "typo"; } +>{ type: "json", ttype: "typo" } : { readonly type: "json"; readonly ttype: "typo"; } +>type : "json" >"json" : "json" ->ttype : string +>ttype : "typo" >"typo" : "typo" const d = import('./0', { with: {} }) @@ -130,9 +130,9 @@ const h = import('./0', { with: { type: "json" }},) >h : Promise >import('./0', { with: { type: "json" }},) : Promise >'./0' : "./0" ->{ with: { type: "json" }} : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" }} : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes2(module=commonjs).js b/tsc/testdata/baselines/reference/conformance/importAttributes2(module=commonjs).js index 0df07d2bbd057..293da2aab76dd 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes2(module=commonjs).js +++ b/tsc/testdata/baselines/reference/conformance/importAttributes2(module=commonjs).js @@ -82,10 +82,10 @@ Object.defineProperty(exports, "d", { enumerable: true, get: function () { retur export declare const a = 1; export declare const b = 2; //// [1.d.ts] -export {} from './0'; -export { a, b } from './0'; -export * from './0'; -export * as ns from './0'; +export {} from './0' with { type: "json" }; +export { a, b } from './0' with { type: "json" }; +export * from './0' with { type: "json" }; +export * as ns from './0' with { type: "json" }; //// [2.d.ts] -export { a, b } from './0'; -export { a as c, b as d } from './0'; +export { a, b } from './0' with {}; +export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes2(module=es2015).js b/tsc/testdata/baselines/reference/conformance/importAttributes2(module=es2015).js index b3105648f5715..9bcef3ae122d5 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes2(module=es2015).js +++ b/tsc/testdata/baselines/reference/conformance/importAttributes2(module=es2015).js @@ -32,10 +32,10 @@ export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; export declare const a = 1; export declare const b = 2; //// [1.d.ts] -export {} from './0'; -export { a, b } from './0'; -export * from './0'; -export * as ns from './0'; +export {} from './0' with { type: "json" }; +export { a, b } from './0' with { type: "json" }; +export * from './0' with { type: "json" }; +export * as ns from './0' with { type: "json" }; //// [2.d.ts] -export { a, b } from './0'; -export { a as c, b as d } from './0'; +export { a, b } from './0' with {}; +export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes2(module=esnext).js b/tsc/testdata/baselines/reference/conformance/importAttributes2(module=esnext).js index 954e66a8db191..ef98aff54b76b 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes2(module=esnext).js +++ b/tsc/testdata/baselines/reference/conformance/importAttributes2(module=esnext).js @@ -31,10 +31,10 @@ export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; export declare const a = 1; export declare const b = 2; //// [1.d.ts] -export {} from './0'; -export { a, b } from './0'; -export * from './0'; -export * as ns from './0'; +export {} from './0' with { type: "json" }; +export { a, b } from './0' with { type: "json" }; +export * from './0' with { type: "json" }; +export * as ns from './0' with { type: "json" }; //// [2.d.ts] -export { a, b } from './0'; -export { a as c, b as d } from './0'; +export { a, b } from './0' with {}; +export { a as c, b as d } from './0' with { a: "a", b: "b", c: "c" }; diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).errors.txt b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).errors.txt deleted file mode 100644 index 069b64d9d3bb1..0000000000000 --- a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).errors.txt +++ /dev/null @@ -1,25 +0,0 @@ -1.ts(1,27): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -1.ts(2,30): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -2.ts(1,31): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -2.ts(2,33): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - - -==== 0.ts (0 errors) ==== - export interface I { } - -==== 1.ts (2 errors) ==== - export type {} from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - export type { I } from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - -==== 2.ts (2 errors) ==== - import type { I } from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - import type * as foo from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).js b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).js index 493e570835215..ba10177b6384a 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).js +++ b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).js @@ -24,7 +24,7 @@ export {}; export interface I { } //// [1.d.ts] -export type {} from './0'; -export type { I } from './0'; +export type {} from './0' with { type: "json" }; +export type { I } from './0' with { type: "json" }; //// [2.d.ts] export {}; diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).types b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).types index 7b71ed23ded61..0d5cddf12aac3 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).types +++ b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=es2015).types @@ -6,18 +6,18 @@ export interface I { } === 1.ts === export type {} from './0' with { type: "json" } ->type : any +>type : error export type { I } from './0' with { type: "json" } >I : import("./0").I ->type : any +>type : error === 2.ts === import type { I } from './0' with { type: "json" } >I : I ->type : any +>type : error import type * as foo from './0' with { type: "json" } >foo : typeof foo ->type : any +>type : error diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).errors.txt b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).errors.txt deleted file mode 100644 index c6b8edc12f183..0000000000000 --- a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).errors.txt +++ /dev/null @@ -1,25 +0,0 @@ -1.ts(1,27): error TS2857: Import attributes cannot be used with type-only imports or exports. -1.ts(2,30): error TS2857: Import attributes cannot be used with type-only imports or exports. -2.ts(1,31): error TS2857: Import attributes cannot be used with type-only imports or exports. -2.ts(2,33): error TS2857: Import attributes cannot be used with type-only imports or exports. - - -==== 0.ts (0 errors) ==== - export interface I { } - -==== 1.ts (2 errors) ==== - export type {} from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - export type { I } from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - -==== 2.ts (2 errors) ==== - import type { I } from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - import type * as foo from './0' with { type: "json" } - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).js b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).js index 493e570835215..ba10177b6384a 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).js +++ b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).js @@ -24,7 +24,7 @@ export {}; export interface I { } //// [1.d.ts] -export type {} from './0'; -export type { I } from './0'; +export type {} from './0' with { type: "json" }; +export type { I } from './0' with { type: "json" }; //// [2.d.ts] export {}; diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).types b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).types index 7b71ed23ded61..0d5cddf12aac3 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).types +++ b/tsc/testdata/baselines/reference/conformance/importAttributes3(module=esnext).types @@ -6,18 +6,18 @@ export interface I { } === 1.ts === export type {} from './0' with { type: "json" } ->type : any +>type : error export type { I } from './0' with { type: "json" } >I : import("./0").I ->type : any +>type : error === 2.ts === import type { I } from './0' with { type: "json" } >I : I ->type : any +>type : error import type * as foo from './0' with { type: "json" } >foo : typeof foo ->type : any +>type : error diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes7.types b/tsc/testdata/baselines/reference/conformance/importAttributes7.types index 4a5164a5d9039..984a9fd565263 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes7.types +++ b/tsc/testdata/baselines/reference/conformance/importAttributes7.types @@ -29,14 +29,14 @@ export async function f() { >a : Promise >import("./a", { with: { a: "a", "b": "b" }, }) : Promise >"./a" : "./a" ->{ with: { a: "a", "b": "b" }, } : { with: { a: string; b: string; }; } +>{ with: { a: "a", "b": "b" }, } : { with: { readonly a: "a"; readonly b: "b"; }; } with: { a: "a", "b": "b" }, ->with : { a: string; b: string; } ->{ a: "a", "b": "b" } : { a: string; b: string; } ->a : string +>with : { readonly a: "a"; readonly b: "b"; } +>{ a: "a", "b": "b" } : { readonly a: "a"; readonly b: "b"; } +>a : "a" >"a" : "a" ->"b" : string +>"b" : "b" >"b" : "b" }); diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes9.errors.txt b/tsc/testdata/baselines/reference/conformance/importAttributes9.errors.txt index a0308ee88e5ba..b22d96959b784 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes9.errors.txt +++ b/tsc/testdata/baselines/reference/conformance/importAttributes9.errors.txt @@ -1,7 +1,7 @@ b.ts(7,27): error TS2322: Type '{ type: "not-json"; }' is not assignable to type 'ImportAttributes'. Types of property 'type' are incompatible. Type '"not-json"' is not assignable to type '"json"'. -b.ts(11,25): error TS2322: Type '{ with: { type: "not-json"; }; }' is not assignable to type 'ImportCallOptions'. +b.ts(11,25): error TS2322: Type '{ with: { readonly type: "not-json"; }; }' is not assignable to type 'ImportCallOptions'. The types of 'with.type' are incompatible between these types. Type '"not-json"' is not assignable to type '"json"'. @@ -34,7 +34,7 @@ b.ts(11,25): error TS2322: Type '{ with: { type: "not-json"; }; }' is not assign ~~~~~~~~~~ }); ~~~~~ -!!! error TS2322: Type '{ with: { type: "not-json"; }; }' is not assignable to type 'ImportCallOptions'. +!!! error TS2322: Type '{ with: { readonly type: "not-json"; }; }' is not assignable to type 'ImportCallOptions'. !!! error TS2322: The types of 'with.type' are incompatible between these types. !!! error TS2322: Type '"not-json"' is not assignable to type '"json"'. } diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes9.types b/tsc/testdata/baselines/reference/conformance/importAttributes9.types index cafc6de21fc9e..d8e1ef7c4aada 100644 --- a/tsc/testdata/baselines/reference/conformance/importAttributes9.types +++ b/tsc/testdata/baselines/reference/conformance/importAttributes9.types @@ -29,11 +29,11 @@ async function f() { >await import("./a", { with: { type: "not-json", }, }) : typeof import("./a") >import("./a", { with: { type: "not-json", }, }) : Promise >"./a" : "./a" ->{ with: { type: "not-json", }, } : { with: { type: "not-json"; }; } +>{ with: { type: "not-json", }, } : { with: { readonly type: "not-json"; }; } with: { ->with : { type: "not-json"; } ->{ type: "not-json", } : { type: "not-json"; } +>with : { readonly type: "not-json"; } +>{ type: "not-json", } : { readonly type: "not-json"; } type: "not-json", >type : "not-json" diff --git a/tsc/testdata/baselines/reference/conformance/importTag14.errors.txt b/tsc/testdata/baselines/reference/conformance/importTag14.errors.txt index 6109dd03ca40f..9538015871594 100644 --- a/tsc/testdata/baselines/reference/conformance/importTag14.errors.txt +++ b/tsc/testdata/baselines/reference/conformance/importTag14.errors.txt @@ -1,17 +1,11 @@ /foo.js(1,25): error TS2306: File '/foo.js' is not a module. -/foo.js(1,33): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. -/foo.js(1,33): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. /foo.js(1,38): error TS1005: '{' expected. -==== /foo.js (4 errors) ==== +==== /foo.js (2 errors) ==== /** @import * as f from "./foo" with */ ~~~~~~~ !!! error TS2306: File '/foo.js' is not a module. - ~~~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. - ~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. !!! error TS1005: '{' expected. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/importTag15(module=es2015).errors.txt b/tsc/testdata/baselines/reference/conformance/importTag15(module=es2015).errors.txt deleted file mode 100644 index ae3f68aaa071e..0000000000000 --- a/tsc/testdata/baselines/reference/conformance/importTag15(module=es2015).errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -1.js(1,30): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -1.js(2,33): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - - -==== 0.ts (0 errors) ==== - export interface I { } - -==== 1.js (2 errors) ==== - /** @import { I } from './0' with { type: "json" } */ - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - /** @import * as foo from './0' with { type: "json" } */ - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. - - /** @param {I} a */ - function f(a) {} - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/importTag15(module=es2015).js b/tsc/testdata/baselines/reference/conformance/importTag15(module=es2015).js index e2d9c515d3735..2ade94c80ebc1 100644 --- a/tsc/testdata/baselines/reference/conformance/importTag15(module=es2015).js +++ b/tsc/testdata/baselines/reference/conformance/importTag15(module=es2015).js @@ -19,6 +19,6 @@ export interface I { //// [1.d.ts] /** @import { I } from './0' with { type: "json" } */ /** @import * as foo from './0' with { type: "json" } */ -import type { I } from './0'; +import type { I } from './0' with { type: "json" }; /** @param {I} a */ declare function f(a: I): void; diff --git a/tsc/testdata/baselines/reference/conformance/importTag15(module=esnext).errors.txt b/tsc/testdata/baselines/reference/conformance/importTag15(module=esnext).errors.txt deleted file mode 100644 index 3b98c15768bff..0000000000000 --- a/tsc/testdata/baselines/reference/conformance/importTag15(module=esnext).errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -1.js(1,30): error TS2857: Import attributes cannot be used with type-only imports or exports. -1.js(2,33): error TS2857: Import attributes cannot be used with type-only imports or exports. - - -==== 0.ts (0 errors) ==== - export interface I { } - -==== 1.js (2 errors) ==== - /** @import { I } from './0' with { type: "json" } */ - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - /** @import * as foo from './0' with { type: "json" } */ - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. - - /** @param {I} a */ - function f(a) {} - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/importTag15(module=esnext).js b/tsc/testdata/baselines/reference/conformance/importTag15(module=esnext).js index e2d9c515d3735..2ade94c80ebc1 100644 --- a/tsc/testdata/baselines/reference/conformance/importTag15(module=esnext).js +++ b/tsc/testdata/baselines/reference/conformance/importTag15(module=esnext).js @@ -19,6 +19,6 @@ export interface I { //// [1.d.ts] /** @import { I } from './0' with { type: "json" } */ /** @import * as foo from './0' with { type: "json" } */ -import type { I } from './0'; +import type { I } from './0' with { type: "json" }; /** @param {I} a */ declare function f(a: I): void; diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node16).types b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node16).types index c3d1b505ac239..52bff0143607b 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node16).types +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node16).types @@ -14,10 +14,10 @@ const json2 = import("./package.json", { with: { type: "json" } }); // should be >json2 : Promise<{ default: { name: string; private: boolean; type: string; }; }> >import("./package.json", { with: { type: "json" } }) : Promise<{ default: { name: string; private: boolean; type: string; }; }> >"./package.json" : "./package.json" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" === package.json === diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node18).types b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node18).types index c3d1b505ac239..52bff0143607b 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node18).types +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node18).types @@ -14,10 +14,10 @@ const json2 = import("./package.json", { with: { type: "json" } }); // should be >json2 : Promise<{ default: { name: string; private: boolean; type: string; }; }> >import("./package.json", { with: { type: "json" } }) : Promise<{ default: { name: string; private: boolean; type: string; }; }> >"./package.json" : "./package.json" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" === package.json === diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node20).types b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node20).types index c3d1b505ac239..52bff0143607b 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node20).types +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=node20).types @@ -14,10 +14,10 @@ const json2 = import("./package.json", { with: { type: "json" } }); // should be >json2 : Promise<{ default: { name: string; private: boolean; type: string; }; }> >import("./package.json", { with: { type: "json" } }) : Promise<{ default: { name: string; private: boolean; type: string; }; }> >"./package.json" : "./package.json" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" === package.json === diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=nodenext).types b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=nodenext).types index c3d1b505ac239..52bff0143607b 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=nodenext).types +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAssertions(module=nodenext).types @@ -14,10 +14,10 @@ const json2 = import("./package.json", { with: { type: "json" } }); // should be >json2 : Promise<{ default: { name: string; private: boolean; type: string; }; }> >import("./package.json", { with: { type: "json" } }) : Promise<{ default: { name: string; private: boolean; type: string; }; }> >"./package.json" : "./package.json" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" === package.json === diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node16).types b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node16).types index a6b4943e6debe..1177163581a6e 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node16).types +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node16).types @@ -14,10 +14,10 @@ const json2 = import("./package.json", { with: { type: "json" } }); // should be >json2 : Promise<{ default: { name: string; private: boolean; type: string; }; }> >import("./package.json", { with: { type: "json" } }) : Promise<{ default: { name: string; private: boolean; type: string; }; }> >"./package.json" : "./package.json" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" === package.json === diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node18).types b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node18).types index a6b4943e6debe..1177163581a6e 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node18).types +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node18).types @@ -14,10 +14,10 @@ const json2 = import("./package.json", { with: { type: "json" } }); // should be >json2 : Promise<{ default: { name: string; private: boolean; type: string; }; }> >import("./package.json", { with: { type: "json" } }) : Promise<{ default: { name: string; private: boolean; type: string; }; }> >"./package.json" : "./package.json" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" === package.json === diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node20).types b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node20).types index a6b4943e6debe..1177163581a6e 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node20).types +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=node20).types @@ -14,10 +14,10 @@ const json2 = import("./package.json", { with: { type: "json" } }); // should be >json2 : Promise<{ default: { name: string; private: boolean; type: string; }; }> >import("./package.json", { with: { type: "json" } }) : Promise<{ default: { name: string; private: boolean; type: string; }; }> >"./package.json" : "./package.json" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" === package.json === diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=nodenext).types b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=nodenext).types index a6b4943e6debe..1177163581a6e 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=nodenext).types +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributes(module=nodenext).types @@ -14,10 +14,10 @@ const json2 = import("./package.json", { with: { type: "json" } }); // should be >json2 : Promise<{ default: { name: string; private: boolean; type: string; }; }> >import("./package.json", { with: { type: "json" } }) : Promise<{ default: { name: string; private: boolean; type: string; }; }> >"./package.json" : "./package.json" ->{ with: { type: "json" } } : { with: { type: string; }; } ->with : { type: string; } ->{ type: "json" } : { type: string; } ->type : string +>{ with: { type: "json" } } : { with: { readonly type: "json"; }; } +>with : { readonly type: "json"; } +>{ type: "json" } : { readonly type: "json"; } +>type : "json" >"json" : "json" === package.json === diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).errors.txt index 9a813ef6db3fa..578244ccbc51f 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).errors.txt @@ -1,15 +1,12 @@ -/index.ts(2,45): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. /index.ts(2,71): error TS1453: `resolution-mode` should be either `require` or `import`. /index.ts(4,10): error TS2305: Module '"pkg"' has no exported member 'ImportInterface'. /index.ts(4,39): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. /index.ts(6,76): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -==== /index.ts (5 errors) ==== +==== /index.ts (4 errors) ==== // incorrect mode import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. ~~~~~~~~ !!! error TS1453: `resolution-mode` should be either `require` or `import`. // not type-only diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js index 988072b042c93..9c3bad6ab3856 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js @@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [index.d.ts] -import type { RequireInterface } from "pkg"; +import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; import { ImportInterface } from "pkg" with { "resolution-mode": "import" }; export interface LocalInterface extends RequireInterface, ImportInterface { } diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).errors.txt index c45ca1322b3a8..162db83add8a4 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).errors.txt @@ -1,15 +1,12 @@ -/index.ts(2,45): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(2,71): error TS1453: `resolution-mode` should be either `require` or `import`. /index.ts(4,10): error TS2305: Module '"pkg"' has no exported member 'ImportInterface'. /index.ts(4,39): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(6,76): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. -==== /index.ts (5 errors) ==== +==== /index.ts (4 errors) ==== // incorrect mode import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. ~~~~~~~~ !!! error TS1453: `resolution-mode` should be either `require` or `import`. // not type-only diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js index 988072b042c93..9c3bad6ab3856 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js @@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [index.d.ts] -import type { RequireInterface } from "pkg"; +import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; import { ImportInterface } from "pkg" with { "resolution-mode": "import" }; export interface LocalInterface extends RequireInterface, ImportInterface { } diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).errors.txt index c45ca1322b3a8..162db83add8a4 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).errors.txt @@ -1,15 +1,12 @@ -/index.ts(2,45): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(2,71): error TS1453: `resolution-mode` should be either `require` or `import`. /index.ts(4,10): error TS2305: Module '"pkg"' has no exported member 'ImportInterface'. /index.ts(4,39): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(6,76): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. -==== /index.ts (5 errors) ==== +==== /index.ts (4 errors) ==== // incorrect mode import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. ~~~~~~~~ !!! error TS1453: `resolution-mode` should be either `require` or `import`. // not type-only diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js index 988072b042c93..9c3bad6ab3856 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js @@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [index.d.ts] -import type { RequireInterface } from "pkg"; +import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; import { ImportInterface } from "pkg" with { "resolution-mode": "import" }; export interface LocalInterface extends RequireInterface, ImportInterface { } diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).errors.txt index c45ca1322b3a8..162db83add8a4 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).errors.txt @@ -1,15 +1,12 @@ -/index.ts(2,45): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(2,71): error TS1453: `resolution-mode` should be either `require` or `import`. /index.ts(4,10): error TS2305: Module '"pkg"' has no exported member 'ImportInterface'. /index.ts(4,39): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(6,76): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. -==== /index.ts (5 errors) ==== +==== /index.ts (4 errors) ==== // incorrect mode import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. ~~~~~~~~ !!! error TS1453: `resolution-mode` should be either `require` or `import`. // not type-only diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js index 988072b042c93..9c3bad6ab3856 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js @@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [index.d.ts] -import type { RequireInterface } from "pkg"; +import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; import { ImportInterface } from "pkg" with { "resolution-mode": "import" }; export interface LocalInterface extends RequireInterface, ImportInterface { } diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node16).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node16).errors.txt index 2d2f2c5b8ffbb..43aeb3f7a5b8f 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node16).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node16).errors.txt @@ -27,11 +27,7 @@ /other.ts(7,79): error TS1434: Unexpected keyword or identifier. /other.ts(7,79): error TS2304: Cannot find name 'ImportInterface'. /other.ts(7,94): error TS1128: Declaration or statement expected. -/other2.ts(3,30): error TS1463: 'resolution-mode' is the only valid key for type import attributes. -/other2.ts(4,30): error TS1463: 'resolution-mode' is the only valid key for type import attributes. /other2.ts(4,50): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. -/other2.ts(6,57): error TS1463: 'resolution-mode' is the only valid key for type import attributes. -/other2.ts(7,57): error TS1463: 'resolution-mode' is the only valid key for type import attributes. /other2.ts(7,77): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. /other3.ts(3,7): error TS1340: Module 'pkg' does not refer to a type, but is used as a type here. Did you mean 'typeof import('pkg')'? /other3.ts(3,21): error TS1005: '{' expected. @@ -67,11 +63,7 @@ /other4.ts(10,58): error TS1005: ',' expected. /other4.ts(10,59): error TS1134: Variable declaration expected. /other4.ts(10,75): error TS1005: ',' expected. -/other5.ts(2,29): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. -/other5.ts(3,29): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. /other5.ts(3,35): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. -/other5.ts(5,56): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. -/other5.ts(6,56): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. /other5.ts(6,62): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. @@ -168,24 +160,16 @@ ~ !!! error TS1128: Declaration or statement expected. -==== /other2.ts (6 errors) ==== +==== /other2.ts (2 errors) ==== // wrong attribute key export type LocalInterface = & import("pkg", { with: {"bad": "require"} }).RequireInterface - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. & import("pkg", { with: {"bad": "import"} }).ImportInterface; - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. export const a = (null as any as import("pkg", { with: {"bad": "require"} }).RequireInterface); - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. export const b = (null as any as import("pkg", { with: {"bad": "import"} }).ImportInterface); - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. @@ -287,22 +271,14 @@ ~ !!! error TS1005: ',' expected. -==== /other5.ts (6 errors) ==== +==== /other5.ts (2 errors) ==== export type LocalInterface = & import("pkg", { with: {} }).RequireInterface - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. & import("pkg", { with: {} }).ImportInterface; - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. export const a = (null as any as import("pkg", { with: {} }).RequireInterface); - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. export const b = (null as any as import("pkg", { with: {} }).ImportInterface); - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node18).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node18).errors.txt index 2d2f2c5b8ffbb..43aeb3f7a5b8f 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node18).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node18).errors.txt @@ -27,11 +27,7 @@ /other.ts(7,79): error TS1434: Unexpected keyword or identifier. /other.ts(7,79): error TS2304: Cannot find name 'ImportInterface'. /other.ts(7,94): error TS1128: Declaration or statement expected. -/other2.ts(3,30): error TS1463: 'resolution-mode' is the only valid key for type import attributes. -/other2.ts(4,30): error TS1463: 'resolution-mode' is the only valid key for type import attributes. /other2.ts(4,50): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. -/other2.ts(6,57): error TS1463: 'resolution-mode' is the only valid key for type import attributes. -/other2.ts(7,57): error TS1463: 'resolution-mode' is the only valid key for type import attributes. /other2.ts(7,77): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. /other3.ts(3,7): error TS1340: Module 'pkg' does not refer to a type, but is used as a type here. Did you mean 'typeof import('pkg')'? /other3.ts(3,21): error TS1005: '{' expected. @@ -67,11 +63,7 @@ /other4.ts(10,58): error TS1005: ',' expected. /other4.ts(10,59): error TS1134: Variable declaration expected. /other4.ts(10,75): error TS1005: ',' expected. -/other5.ts(2,29): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. -/other5.ts(3,29): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. /other5.ts(3,35): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. -/other5.ts(5,56): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. -/other5.ts(6,56): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. /other5.ts(6,62): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. @@ -168,24 +160,16 @@ ~ !!! error TS1128: Declaration or statement expected. -==== /other2.ts (6 errors) ==== +==== /other2.ts (2 errors) ==== // wrong attribute key export type LocalInterface = & import("pkg", { with: {"bad": "require"} }).RequireInterface - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. & import("pkg", { with: {"bad": "import"} }).ImportInterface; - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. export const a = (null as any as import("pkg", { with: {"bad": "require"} }).RequireInterface); - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. export const b = (null as any as import("pkg", { with: {"bad": "import"} }).ImportInterface); - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. @@ -287,22 +271,14 @@ ~ !!! error TS1005: ',' expected. -==== /other5.ts (6 errors) ==== +==== /other5.ts (2 errors) ==== export type LocalInterface = & import("pkg", { with: {} }).RequireInterface - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. & import("pkg", { with: {} }).ImportInterface; - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. export const a = (null as any as import("pkg", { with: {} }).RequireInterface); - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. export const b = (null as any as import("pkg", { with: {} }).ImportInterface); - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node20).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node20).errors.txt index 2d2f2c5b8ffbb..43aeb3f7a5b8f 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node20).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=node20).errors.txt @@ -27,11 +27,7 @@ /other.ts(7,79): error TS1434: Unexpected keyword or identifier. /other.ts(7,79): error TS2304: Cannot find name 'ImportInterface'. /other.ts(7,94): error TS1128: Declaration or statement expected. -/other2.ts(3,30): error TS1463: 'resolution-mode' is the only valid key for type import attributes. -/other2.ts(4,30): error TS1463: 'resolution-mode' is the only valid key for type import attributes. /other2.ts(4,50): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. -/other2.ts(6,57): error TS1463: 'resolution-mode' is the only valid key for type import attributes. -/other2.ts(7,57): error TS1463: 'resolution-mode' is the only valid key for type import attributes. /other2.ts(7,77): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. /other3.ts(3,7): error TS1340: Module 'pkg' does not refer to a type, but is used as a type here. Did you mean 'typeof import('pkg')'? /other3.ts(3,21): error TS1005: '{' expected. @@ -67,11 +63,7 @@ /other4.ts(10,58): error TS1005: ',' expected. /other4.ts(10,59): error TS1134: Variable declaration expected. /other4.ts(10,75): error TS1005: ',' expected. -/other5.ts(2,29): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. -/other5.ts(3,29): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. /other5.ts(3,35): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. -/other5.ts(5,56): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. -/other5.ts(6,56): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. /other5.ts(6,62): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. @@ -168,24 +160,16 @@ ~ !!! error TS1128: Declaration or statement expected. -==== /other2.ts (6 errors) ==== +==== /other2.ts (2 errors) ==== // wrong attribute key export type LocalInterface = & import("pkg", { with: {"bad": "require"} }).RequireInterface - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. & import("pkg", { with: {"bad": "import"} }).ImportInterface; - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. export const a = (null as any as import("pkg", { with: {"bad": "require"} }).RequireInterface); - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. export const b = (null as any as import("pkg", { with: {"bad": "import"} }).ImportInterface); - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. @@ -287,22 +271,14 @@ ~ !!! error TS1005: ',' expected. -==== /other5.ts (6 errors) ==== +==== /other5.ts (2 errors) ==== export type LocalInterface = & import("pkg", { with: {} }).RequireInterface - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. & import("pkg", { with: {} }).ImportInterface; - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. export const a = (null as any as import("pkg", { with: {} }).RequireInterface); - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. export const b = (null as any as import("pkg", { with: {} }).ImportInterface); - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=nodenext).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=nodenext).errors.txt index 2d2f2c5b8ffbb..43aeb3f7a5b8f 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=nodenext).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportAttributesTypeModeDeclarationEmitErrors(module=nodenext).errors.txt @@ -27,11 +27,7 @@ /other.ts(7,79): error TS1434: Unexpected keyword or identifier. /other.ts(7,79): error TS2304: Cannot find name 'ImportInterface'. /other.ts(7,94): error TS1128: Declaration or statement expected. -/other2.ts(3,30): error TS1463: 'resolution-mode' is the only valid key for type import attributes. -/other2.ts(4,30): error TS1463: 'resolution-mode' is the only valid key for type import attributes. /other2.ts(4,50): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. -/other2.ts(6,57): error TS1463: 'resolution-mode' is the only valid key for type import attributes. -/other2.ts(7,57): error TS1463: 'resolution-mode' is the only valid key for type import attributes. /other2.ts(7,77): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. /other3.ts(3,7): error TS1340: Module 'pkg' does not refer to a type, but is used as a type here. Did you mean 'typeof import('pkg')'? /other3.ts(3,21): error TS1005: '{' expected. @@ -67,11 +63,7 @@ /other4.ts(10,58): error TS1005: ',' expected. /other4.ts(10,59): error TS1134: Variable declaration expected. /other4.ts(10,75): error TS1005: ',' expected. -/other5.ts(2,29): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. -/other5.ts(3,29): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. /other5.ts(3,35): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. -/other5.ts(5,56): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. -/other5.ts(6,56): error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. /other5.ts(6,62): error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. @@ -168,24 +160,16 @@ ~ !!! error TS1128: Declaration or statement expected. -==== /other2.ts (6 errors) ==== +==== /other2.ts (2 errors) ==== // wrong attribute key export type LocalInterface = & import("pkg", { with: {"bad": "require"} }).RequireInterface - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. & import("pkg", { with: {"bad": "import"} }).ImportInterface; - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. export const a = (null as any as import("pkg", { with: {"bad": "require"} }).RequireInterface); - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. export const b = (null as any as import("pkg", { with: {"bad": "import"} }).ImportInterface); - ~~~~~ -!!! error TS1463: 'resolution-mode' is the only valid key for type import attributes. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. @@ -287,22 +271,14 @@ ~ !!! error TS1005: ',' expected. -==== /other5.ts (6 errors) ==== +==== /other5.ts (2 errors) ==== export type LocalInterface = & import("pkg", { with: {} }).RequireInterface - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. & import("pkg", { with: {} }).ImportInterface; - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. export const a = (null as any as import("pkg", { with: {} }).RequireInterface); - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. export const b = (null as any as import("pkg", { with: {} }).ImportInterface); - ~~ -!!! error TS1464: Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'. ~~~~~~~~~~~~~~~ !!! error TS2694: Namespace '"/node_modules/pkg/require"' has no exported member 'ImportInterface'. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).errors.txt index 9a813ef6db3fa..578244ccbc51f 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).errors.txt @@ -1,15 +1,12 @@ -/index.ts(2,45): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. /index.ts(2,71): error TS1453: `resolution-mode` should be either `require` or `import`. /index.ts(4,10): error TS2305: Module '"pkg"' has no exported member 'ImportInterface'. /index.ts(4,39): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. /index.ts(6,76): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -==== /index.ts (5 errors) ==== +==== /index.ts (4 errors) ==== // incorrect mode import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. ~~~~~~~~ !!! error TS1453: `resolution-mode` should be either `require` or `import`. // not type-only diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js index 2f14482b2747a..88738694120cb 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js @@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [index.d.ts] -import type { RequireInterface } from "pkg"; +import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; import { ImportInterface } from "pkg" with { "resolution-mode": "import" }; export interface LocalInterface extends RequireInterface, ImportInterface { } diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).errors.txt index c45ca1322b3a8..162db83add8a4 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).errors.txt @@ -1,15 +1,12 @@ -/index.ts(2,45): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(2,71): error TS1453: `resolution-mode` should be either `require` or `import`. /index.ts(4,10): error TS2305: Module '"pkg"' has no exported member 'ImportInterface'. /index.ts(4,39): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(6,76): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. -==== /index.ts (5 errors) ==== +==== /index.ts (4 errors) ==== // incorrect mode import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. ~~~~~~~~ !!! error TS1453: `resolution-mode` should be either `require` or `import`. // not type-only diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js index 2f14482b2747a..88738694120cb 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js @@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [index.d.ts] -import type { RequireInterface } from "pkg"; +import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; import { ImportInterface } from "pkg" with { "resolution-mode": "import" }; export interface LocalInterface extends RequireInterface, ImportInterface { } diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).errors.txt index c45ca1322b3a8..162db83add8a4 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).errors.txt @@ -1,15 +1,12 @@ -/index.ts(2,45): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(2,71): error TS1453: `resolution-mode` should be either `require` or `import`. /index.ts(4,10): error TS2305: Module '"pkg"' has no exported member 'ImportInterface'. /index.ts(4,39): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(6,76): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. -==== /index.ts (5 errors) ==== +==== /index.ts (4 errors) ==== // incorrect mode import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. ~~~~~~~~ !!! error TS1453: `resolution-mode` should be either `require` or `import`. // not type-only diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js index 2f14482b2747a..88738694120cb 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js @@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [index.d.ts] -import type { RequireInterface } from "pkg"; +import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; import { ImportInterface } from "pkg" with { "resolution-mode": "import" }; export interface LocalInterface extends RequireInterface, ImportInterface { } diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).errors.txt index c45ca1322b3a8..162db83add8a4 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).errors.txt @@ -1,15 +1,12 @@ -/index.ts(2,45): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(2,71): error TS1453: `resolution-mode` should be either `require` or `import`. /index.ts(4,10): error TS2305: Module '"pkg"' has no exported member 'ImportInterface'. /index.ts(4,39): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. /index.ts(6,76): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. -==== /index.ts (5 errors) ==== +==== /index.ts (4 errors) ==== // incorrect mode import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls. ~~~~~~~~ !!! error TS1453: `resolution-mode` should be either `require` or `import`. // not type-only diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js index 2f14482b2747a..88738694120cb 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js @@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); //// [index.d.ts] -import type { RequireInterface } from "pkg"; +import type { RequireInterface } from "pkg" with { "resolution-mode": "foobar" }; import { ImportInterface } from "pkg" with { "resolution-mode": "import" }; export interface LocalInterface extends RequireInterface, ImportInterface { } diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node16).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node16).errors.txt index f0a9b3b5f8c30..6e4240dbe0589 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node16).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node16).errors.txt @@ -2,7 +2,6 @@ /loosey.cts(6,9): error TS2339: Property 'default' does not exist on type '{ version: number; }'. /main.mts(5,36): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. /main.mts(6,52): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. -/main.mts(9,47): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. /main.mts(10,10): error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'Node16'. /main.mts(10,41): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. /main.mts(11,42): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. @@ -43,7 +42,7 @@ "version": 1 } -==== /main.mts (7 errors) ==== +==== /main.mts (6 errors) ==== import { oops } from "not.json"; // Ok import moreOops from "actually-json"; // Error in nodenext import typed from "actually-json/typed"; // Error in nodenext @@ -57,8 +56,6 @@ import config2 from "./config.json"; // Error in nodenext, no attribute import type config2Type from "./config.json"; // Ok, type-only import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'. import { version } from "./config.json" with { type: "json" }; // Error, named import ~~~~~~~ !!! error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'Node16'. diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node18).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node18).errors.txt index 4ba7849c2d719..bf91cb9e79bb3 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node18).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node18).errors.txt @@ -3,7 +3,6 @@ /main.mts(2,22): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'Node18'. /main.mts(3,19): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'Node18'. /main.mts(7,21): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'Node18'. -/main.mts(9,47): error TS2857: Import attributes cannot be used with type-only imports or exports. /main.mts(10,10): error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'Node18'. /main.mts(12,9): error TS2339: Property 'version' does not exist on type '{ default: { version: number; }; }'. @@ -42,7 +41,7 @@ "version": 1 } -==== /main.mts (6 errors) ==== +==== /main.mts (5 errors) ==== import { oops } from "not.json"; // Ok import moreOops from "actually-json"; // Error in nodenext ~~~~~~~~~~~~~~~ @@ -58,8 +57,6 @@ !!! error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'Node18'. import type config2Type from "./config.json"; // Ok, type-only import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. import { version } from "./config.json" with { type: "json" }; // Error, named import ~~~~~~~ !!! error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'Node18'. diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node20).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node20).errors.txt index d828b1b8da6c8..a722b42ebca16 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node20).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=node20).errors.txt @@ -3,7 +3,6 @@ /main.mts(2,22): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'Node20'. /main.mts(3,19): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'Node20'. /main.mts(7,21): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'Node20'. -/main.mts(9,47): error TS2857: Import attributes cannot be used with type-only imports or exports. /main.mts(10,10): error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'Node20'. /main.mts(12,9): error TS2339: Property 'version' does not exist on type '{ default: { version: number; }; }'. @@ -42,7 +41,7 @@ "version": 1 } -==== /main.mts (6 errors) ==== +==== /main.mts (5 errors) ==== import { oops } from "not.json"; // Ok import moreOops from "actually-json"; // Error in nodenext ~~~~~~~~~~~~~~~ @@ -58,8 +57,6 @@ !!! error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'Node20'. import type config2Type from "./config.json"; // Ok, type-only import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. import { version } from "./config.json" with { type: "json" }; // Error, named import ~~~~~~~ !!! error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'Node20'. diff --git a/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=nodenext).errors.txt b/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=nodenext).errors.txt index 04e6a649d3f25..085b55216d00f 100644 --- a/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=nodenext).errors.txt +++ b/tsc/testdata/baselines/reference/conformance/nodeModulesJson(module=nodenext).errors.txt @@ -3,7 +3,6 @@ /main.mts(2,22): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'. /main.mts(3,19): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'. /main.mts(7,21): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'. -/main.mts(9,47): error TS2857: Import attributes cannot be used with type-only imports or exports. /main.mts(10,10): error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'NodeNext'. /main.mts(12,9): error TS2339: Property 'version' does not exist on type '{ default: { version: number; }; }'. @@ -42,7 +41,7 @@ "version": 1 } -==== /main.mts (6 errors) ==== +==== /main.mts (5 errors) ==== import { oops } from "not.json"; // Ok import moreOops from "actually-json"; // Error in nodenext ~~~~~~~~~~~~~~~ @@ -58,8 +57,6 @@ !!! error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'. import type config2Type from "./config.json"; // Ok, type-only import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2857: Import attributes cannot be used with type-only imports or exports. import { version } from "./config.json" with { type: "json" }; // Error, named import ~~~~~~~ !!! error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'NodeNext'. diff --git a/tsc/testdata/baselines/reference/fourslash/quickInfo/quickInfoMergedPatternAmbientModuleWithImportAttributes.baseline b/tsc/testdata/baselines/reference/fourslash/quickInfo/quickInfoMergedPatternAmbientModuleWithImportAttributes.baseline new file mode 100644 index 0000000000000..c968b2c3bcbc4 --- /dev/null +++ b/tsc/testdata/baselines/reference/fourslash/quickInfo/quickInfoMergedPatternAmbientModuleWithImportAttributes.baseline @@ -0,0 +1,171 @@ +// === QuickInfo === +=== /first.d.ts === +// declare module "*.asset" with { type: "css" } { +// ^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | module "*.asset" with { type: "css"; } { +// | let cssOnly: "css"; +// | let cssAlso: "css-also"; +// | } +// | ``` +// | +// | (verbosity level: 1) +// | ---------------------------------------------------------------------- +// ^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | module "*.asset" with { type: "css"; } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// export const cssOnly: "css"; +// } +// declare module "*.asset" with { type: "text" } { +// ^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | module "*.asset" with { type: "text"; } { +// | let textOnly: "text"; +// | let textAlso: "text-also"; +// | } +// | ``` +// | +// | (verbosity level: 1) +// | ---------------------------------------------------------------------- +// ^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | module "*.asset" with { type: "text"; } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// export const textOnly: "text"; +// } +// +[ + { + "marker": { + "Position": 24, + "LSPosition": { + "line": 0, + "character": 24 + }, + "Name": "css", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nmodule \"*.asset\" with { type: \"css\"; }\n```\n" + }, + "range": { + "start": { + "line": 0, + "character": 16 + }, + "end": { + "line": 0, + "character": 23 + } + }, + "canIncreaseVerbosity": true + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 24, + "LSPosition": { + "line": 0, + "character": 24 + }, + "Name": "css", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nmodule \"*.asset\" with { type: \"css\"; } {\n let cssOnly: \"css\";\n let cssAlso: \"css-also\";\n}\n```\n" + }, + "range": { + "start": { + "line": 0, + "character": 16 + }, + "end": { + "line": 0, + "character": 23 + } + } + }, + "verbosityLevel": 1 + } + }, + { + "marker": { + "Position": 107, + "LSPosition": { + "line": 3, + "character": 24 + }, + "Name": "text", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nmodule \"*.asset\" with { type: \"text\"; }\n```\n" + }, + "range": { + "start": { + "line": 3, + "character": 16 + }, + "end": { + "line": 3, + "character": 23 + } + }, + "canIncreaseVerbosity": true + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 107, + "LSPosition": { + "line": 3, + "character": 24 + }, + "Name": "text", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nmodule \"*.asset\" with { type: \"text\"; } {\n let textOnly: \"text\";\n let textAlso: \"text-also\";\n}\n```\n" + }, + "range": { + "start": { + "line": 3, + "character": 16 + }, + "end": { + "line": 3, + "character": 23 + } + } + }, + "verbosityLevel": 1 + } + } +] \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/fourslash/quickInfo/quickInfoPatternAmbientModuleWithImportAttributes.baseline b/tsc/testdata/baselines/reference/fourslash/quickInfo/quickInfoPatternAmbientModuleWithImportAttributes.baseline new file mode 100644 index 0000000000000..90233c1f7fb65 --- /dev/null +++ b/tsc/testdata/baselines/reference/fourslash/quickInfo/quickInfoPatternAmbientModuleWithImportAttributes.baseline @@ -0,0 +1,90 @@ +// === QuickInfo === +=== /quickInfoPatternAmbientModuleWithImportAttributes.ts === +// declare module "*.css" with { type: "css" } { +// ^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | module "*.css" with { type: "css"; } { +// | let styles: { +// | readonly [className: string]: string; +// | }; +// | export { styles as default }; +// | } +// | ``` +// | +// | (verbosity level: 1) +// | ---------------------------------------------------------------------- +// ^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | module "*.css" with { type: "css"; } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// const styles: { readonly [className: string]: string }; +// export default styles; +// } +[ + { + "marker": { + "Position": 22, + "LSPosition": { + "line": 0, + "character": 22 + }, + "Name": "1", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nmodule \"*.css\" with { type: \"css\"; }\n```\n" + }, + "range": { + "start": { + "line": 0, + "character": 16 + }, + "end": { + "line": 0, + "character": 21 + } + }, + "canIncreaseVerbosity": true + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 22, + "LSPosition": { + "line": 0, + "character": 22 + }, + "Name": "1", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nmodule \"*.css\" with { type: \"css\"; } {\n let styles: {\n readonly [className: string]: string;\n };\n export { styles as default };\n}\n```\n" + }, + "range": { + "start": { + "line": 0, + "character": 16 + }, + "end": { + "line": 0, + "character": 21 + } + } + }, + "verbosityLevel": 1 + } + } +] \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/importAttributeArbitraryExtension.ts b/tsc/testdata/tests/cases/compiler/importAttributeArbitraryExtension.ts new file mode 100644 index 0000000000000..ed9d0306eb05a --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributeArbitraryExtension.ts @@ -0,0 +1,18 @@ +// @strict: true +// @module: preserve +// @moduleResolution: bundler +// @allowArbitraryExtensions: true +// @noEmit: true + +// @filename: /types.d.ts +declare module "*.ext" with { type: "custom" } { + export const ambient: "ambient"; +} + +// @filename: /file.d.ext.ts +export const physical: "physical"; + +// @filename: /index.ts +import * as value from "./file.ext" with { type: "custom" }; +value.physical; +value.ambient; \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/importAttributeDuplicatePatternMergedResolution.ts b/tsc/testdata/tests/cases/compiler/importAttributeDuplicatePatternMergedResolution.ts new file mode 100644 index 0000000000000..bf25209626a9d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributeDuplicatePatternMergedResolution.ts @@ -0,0 +1,47 @@ +// @strict: true +// @module: preserve +// @moduleResolution: bundler +// @noEmit: true + +// @filename: /a.d.ts +declare module "*.asset" with { type: "css", format: "module" } { + export const fromA: "a"; +} + +// @filename: /b.d.ts +declare module "*.asset" with { format: "module", type: "css" } { + export const fromB: "b"; +} + +// @filename: /variantsA.d.ts +declare module "*.variant" with { type: "css" } { + export const cssOnly: "css"; +} + +declare module "*.variant" with { type: "text" } { + export const textOnly: "text"; +} + +// @filename: /variantsB.d.ts +declare module "*.variant" with { type: "css" } { + export const cssAlso: "css-also"; +} + +declare module "*.variant" with { type: "text" } { + export const textAlso: "text-also"; +} + +// @filename: /index.ts +import { fromA, fromB } from "./file.asset" with { type: "css", format: "module" }; +import * as css from "./file.variant" with { type: "css" }; +import * as text from "./file.variant" with { type: "text" }; + +const a: "a" = fromA; +const b: "b" = fromB; +const cssValue: "css" = css.cssOnly; +const cssAlsoValue: "css-also" = css.cssAlso; +const textValue: "text" = text.textOnly; +const textAlsoValue: "text-also" = text.textAlso; + +const cssDoesNotHaveText: "textOnly" extends keyof typeof css ? false : true = true; +const textDoesNotHaveCss: "cssOnly" extends keyof typeof text ? false : true = true; \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/importAttributeDynamicImports.ts b/tsc/testdata/tests/cases/compiler/importAttributeDynamicImports.ts new file mode 100644 index 0000000000000..4b8cc9cf15037 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributeDynamicImports.ts @@ -0,0 +1,36 @@ +// @strict: true +// @target: es2020 +// @module: preserve +// @moduleResolution: bundler +// @noEmit: true + +// @filename: /types.d.ts +declare module "*.resource" { + export const kind: "plain"; +} + +declare module "typed/*.resource" with { type: "text" } { + export const kind: "text"; +} + +// @filename: /index.ts +async function test() { + const plain = await import("plain.resource"); + const plainKind: "plain" = plain.kind; + + const attributed = await import("typed/file.resource", { with: { type: "text" } }); + const attributedKind: "text" = attributed.kind; + + const parenthesized = await import("typed/parenthesized.resource", ({ with: { type: "text" } })); + const parenthesizedKind: "text" = parenthesized.kind; + + const options = { with: { type: "text" as const } }; + const attributedWithOptions = await import("typed/other.resource", options); + const attributedWithOptionsKind: "text" = attributedWithOptions.kind; + + const withoutAttributes = await import("typed/unattributed.resource"); + const withoutAttributesKind: "plain" = withoutAttributes.kind; + + const unmatchedAttributes = await import("fallback.resource", { with: { type: "unknown" } }); + const unmatchedAttributesKind: "plain" = unmatchedAttributes.kind; +} \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/importAttributeModuleAugmentations.ts b/tsc/testdata/tests/cases/compiler/importAttributeModuleAugmentations.ts new file mode 100644 index 0000000000000..e011e6e35a12e --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributeModuleAugmentations.ts @@ -0,0 +1,45 @@ +// @strict: true +// @module: preserve +// @moduleResolution: bundler +// @noEmit: true + +// @filename: /types.d.ts +declare module "*.asset" { + export const plain: "plain"; +} + +declare module "attributed/*.asset" with { type: "css" } { + export const attributed: "attributed"; +} + +declare module "*.special" with { type: "special" } { + export const attributed: "attributed"; +} + +// @filename: /augmentations.ts +export {}; + +declare module "merged.asset" { + export const augmented: "augmented"; +} + +declare module "attributed/file.asset" { + export const augmented: "augmented"; +} + +declare module "unattributed.special" { + export const augmented: "augmented"; +} + +// @filename: /index.ts +import * as merged from "merged.asset"; +merged.plain; +merged.augmented; + +import * as attributed from "attributed/file.asset" with { type: "css" }; +attributed.attributed; +attributed.augmented; + +import * as unattributed from "unattributed.special"; +unattributed.attributed; +unattributed.augmented; \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/importAttributeMostSpecificType.ts b/tsc/testdata/tests/cases/compiler/importAttributeMostSpecificType.ts new file mode 100644 index 0000000000000..2c81add282631 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributeMostSpecificType.ts @@ -0,0 +1,31 @@ +// @strict: true +// @module: preserve +// @moduleResolution: bundler +// @noEmit: true + +// @filename: /bun-sqlite.d.ts +declare module "databases/*.sqlite" with { type: "sqlite" } { + const database: { + storage: "external"; + filename: string; + }; + export default database; +} + +declare module "*.sqlite" with { type: "sqlite", embed: "true" } { + const database: { + storage: "embedded"; + contents: Uint8Array; + }; + export default database; +} + +// @filename: /index.ts +import externalDatabase from "databases/app.sqlite" with { type: "sqlite" }; +import embeddedDatabase from "databases/app.sqlite" with { type: "sqlite", embed: "true" }; + +const expectedExternalStorage: "external" = externalDatabase.storage; +const expectedEmbeddedStorage: "embedded" = embeddedDatabase.storage; + +externalDatabase.filename; +embeddedDatabase.contents; \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/importAttributePlainStringAmbientModule.ts b/tsc/testdata/tests/cases/compiler/importAttributePlainStringAmbientModule.ts new file mode 100644 index 0000000000000..99b0b1974f0b7 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributePlainStringAmbientModule.ts @@ -0,0 +1,16 @@ +// @strict: true +// @module: preserve +// @moduleResolution: bundler +// @noEmit: true + +// @filename: /types.d.ts +declare module "plainstring" with { type: "css" } { + export const value: "plain"; +} + +// @filename: /index.ts +import { value as withoutAttributes } from "plainstring"; +import { value as withAttributes } from "plainstring" with { type: "ignored" }; + +const first: "plain" = withoutAttributes; +const second: "plain" = withAttributes; \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/importAttributeType1.ts b/tsc/testdata/tests/cases/compiler/importAttributeType1.ts new file mode 100644 index 0000000000000..4cc75a45eb257 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributeType1.ts @@ -0,0 +1,41 @@ +// @strict: true +// @module: preserve +// @noEmit: true +// @noTypesAndSymbols: true + +// @filename: /valid.d.ts +declare module "*.asset" with { type: "css" } { + const stylesheet: CSSStyleSheet; + export default stylesheet; +} + +declare module "*.text" with { type: "text" } { + const text: string; + export default text; +} + +declare module "*.data" with { type: "json" | "json5" } { + const data: { version: number }; + export default data; +} + +declare module "*.augmentable" { + export interface Existing {} +} +// @filename: /valid.ts +import stylesheet from "./button.asset" with { type: "css" }; +import text from "./license.text" with { type: "text" }; +import data from "./config.data" with { type: "json5" }; + +stylesheet.insertRule(""); +text.toUpperCase(); +data.version.toFixed(); + +// @filename: /checkErrors.d.ts +declare module "*.numberValue" with { type: number } {} +declare module "*.objectValue" with { type: { name: string } } {} +// @filename: /augmentation.ts +export {}; +declare module "file.augmentable" with { type: "css" } { + export interface Added {} +} \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/importAttributeTypeOnlyImports.ts b/tsc/testdata/tests/cases/compiler/importAttributeTypeOnlyImports.ts new file mode 100644 index 0000000000000..5107a858a85dc --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributeTypeOnlyImports.ts @@ -0,0 +1,47 @@ +// @strict: true +// @module: preserve +// @moduleResolution: bundler +// @noEmit: true +// @allowJs: true +// @checkJs: true + +// @filename: /types.d.ts +declare module "*.style" with { type: "css" } { + export interface Style { + kind: "css"; + } +} + +declare module "require/*.style" with { type: "css", "resolution-mode": "require" } { + export interface RequireStyle { + kind: "require-css"; + } +} + +// @filename: /reexports.ts +export type { Style } from "plain.style" with { type: "css" }; +export type { RequireStyle } from "require/reexport.style" with { type: "css", "resolution-mode": "require" }; + +// @filename: /jsdoc.js +/** @import { Style } from "jsdoc.style" with { type: "css" } */ + +/** @type {Style} */ +const jsdocStyle = { kind: "css" }; +const jsdocCssKind = jsdocStyle.kind; + +// @filename: /index.ts +import type { Style } from "plain.style" with { type: "css" }; +import type { RequireStyle } from "require/import.style" with { type: "css", "resolution-mode": "require" }; + +type ImportTypeStyle = import("inline.style", { with: { type: "css" } }).Style; +type ImportTypeRequireStyle = import("require/inline.style", { with: { type: "css", "resolution-mode": "require" } }).RequireStyle; + +declare const importedStyle: Style; +declare const importedRequireStyle: RequireStyle; +declare const importTypeStyle: ImportTypeStyle; +declare const importTypeRequireStyle: ImportTypeRequireStyle; + +const cssKind: "css" = importedStyle.kind; +const requireCssKind: "require-css" = importedRequireStyle.kind; +const importTypeCssKind: "css" = importTypeStyle.kind; +const importTypeRequireCssKind: "require-css" = importTypeRequireStyle.kind; \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/importAttributesDeclarationEmit.ts b/tsc/testdata/tests/cases/compiler/importAttributesDeclarationEmit.ts new file mode 100644 index 0000000000000..ddd46bbd9eaea --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributesDeclarationEmit.ts @@ -0,0 +1,32 @@ +// @target: esnext +// @module: preserve +// @moduleResolution: bundler +// @declaration: true +// @emitDeclarationOnly: true +// @outDir: /out + +// @filename: /types.d.ts +declare module "*.style" with { type: "css" } { + export interface Style { + kind: "css"; + } +} + +declare module "formatted/*.style" with { type: "css", format: "module" } { + export interface FormattedStyle { + kind: "css-module"; + } +} + +// @filename: /index.ts +import type { Style } from "plain.style" with { type: "css" }; +import type { FormattedStyle } from "formatted/import.style" with { type: "css", format: "module" }; + +export interface LocalStyle extends Style {} +export interface LocalFormattedStyle extends FormattedStyle {} + +export type { Style } from "reexport.style" with { type: "css" }; +export type { FormattedStyle } from "formatted/reexport.style" with { type: "css", format: "module" }; + +export type InlineStyle = import("inline.style", { with: { type: "css" } }).Style; +export type InlineFormattedStyle = import("formatted/inline.style", { with: { type: "css", format: "module" } }).FormattedStyle; \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts b/tsc/testdata/tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts new file mode 100644 index 0000000000000..8615e8dcac0a2 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts @@ -0,0 +1,32 @@ +// @strict: true +// @module: preserve +// @moduleResolution: bundler +// @noEmit: true + +// @filename: /a.d.ts +declare module "*.asset" { + export const fromA: "a"; +} + +// @filename: /b.d.ts +declare module "*.asset" { + export const fromB: "b"; +} + +// @filename: /augmentation.ts +export {}; + +declare module "augmented.asset" { + export const augmented: "augmented"; +} + +// @filename: /index.ts +import * as augmented from "augmented.asset"; +augmented.fromA; +augmented.fromB; +augmented.augmented; + +import * as other from "other.asset"; +other.fromA; +other.fromB; +other.augmented; \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/resolutionModeOverrideWithOtherAttributes.ts b/tsc/testdata/tests/cases/compiler/resolutionModeOverrideWithOtherAttributes.ts new file mode 100644 index 0000000000000..7c6c3f3742970 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/resolutionModeOverrideWithOtherAttributes.ts @@ -0,0 +1,27 @@ +// @target: esnext +// @module: preserve +// @moduleResolution: bundler +// @noEmit: true + +// @filename: /node_modules/pkg/package.json +{ + "name": "pkg", + "exports": { + ".": { + "import": "./index.d.mts", + "require": "./index.d.cts" + } + } +} + +// @filename: /node_modules/pkg/index.d.mts +export declare const value: "import"; + +// @filename: /node_modules/pkg/index.d.cts +export declare const value: "require"; + +// @filename: /app.ts +import type { value } from "pkg" with { type: "typescript", "resolution-mode": "require" }; + +declare const expected: "require"; +const actual: typeof value = expected; \ No newline at end of file From 986c352483a553cd7b418183a1a7464cbbbb6786 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 21 Aug 2026 21:39:34 +0000 Subject: [PATCH 2/2] use import attribute id in binder symbol name --- tsc/internal/binder/binder.go | 4 +- .../compiler/importAttributeType2.errors.txt | 31 ++++++++ .../compiler/importAttributeType2.symbols | 67 +++++++++++++++++ .../compiler/importAttributeType2.types | 73 +++++++++++++++++++ ...tModuleAugmentationMergedSymbol.errors.txt | 16 +++- ...ientModuleAugmentationMergedSymbol.symbols | 50 +++++++++++-- ...mbientModuleAugmentationMergedSymbol.types | 36 +++++++++ .../cases/compiler/importAttributeType2.ts | 31 ++++++++ ...rnAmbientModuleAugmentationMergedSymbol.ts | 14 +++- 9 files changed, 311 insertions(+), 11 deletions(-) create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeType2.errors.txt create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeType2.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/importAttributeType2.types create mode 100644 tsc/testdata/tests/cases/compiler/importAttributeType2.ts diff --git a/tsc/internal/binder/binder.go b/tsc/internal/binder/binder.go index 4445a0d515e17..392fb6a4c6715 100644 --- a/tsc/internal/binder/binder.go +++ b/tsc/internal/binder/binder.go @@ -310,7 +310,9 @@ func (b *Binder) getDeclarationName(node *ast.Node) string { return ast.InternalSymbolNameGlobal } if pattern := core.TryParsePattern(moduleName); pattern.IsValid() && pattern.StarIndex >= 0 { - return "\"" + moduleName + "\"" + ast.InternalSymbolNamePrefix + "pattern@" + strconv.FormatUint(uint64(ast.GetNodeId(node)), 10) + if attributes := node.AsModuleDeclaration().Attributes; attributes != nil { + return "\"" + moduleName + "\"" + ast.InternalSymbolNamePrefix + "pattern@" + strconv.FormatUint(uint64(ast.GetNodeId(attributes)), 10) + } } return "\"" + moduleName + "\"" } diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeType2.errors.txt b/tsc/testdata/baselines/reference/compiler/importAttributeType2.errors.txt new file mode 100644 index 0000000000000..182a48288a78b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeType2.errors.txt @@ -0,0 +1,31 @@ +/index.ts(1,25): error TS2307: Cannot find module 'databases/app.sqlite' or its corresponding type declarations. + + +==== /bun-sqlite.d.ts (0 errors) ==== + declare module "databases/*.sqlite" with { type: "sqlite", embed: "false" } { + const database: { + storage: "external"; + filename: string; + }; + export default database; + } + + declare module "*.sqlite" with { type: "sqlite", embed: "true" } { + const database: { + storage: "embedded"; + contents: Uint8Array; + }; + export default database; + } + +==== /index.ts (1 errors) ==== + import badDatabase from "databases/app.sqlite" with { type: "sqlite" }; + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'databases/app.sqlite' or its corresponding type declarations. + import embeddedDatabase from "databases/app.sqlite" with { type: "sqlite", embed: "true" }; + + const expectedExternalStorage: "external" = badDatabase.storage; + const expectedEmbeddedStorage: "embedded" = embeddedDatabase.storage; + + badDatabase.filename; + embeddedDatabase.contents; \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeType2.symbols b/tsc/testdata/baselines/reference/compiler/importAttributeType2.symbols new file mode 100644 index 0000000000000..fac17501d9a7c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeType2.symbols @@ -0,0 +1,67 @@ +//// [tests/cases/compiler/importAttributeType2.ts] //// + +=== /bun-sqlite.d.ts === +declare module "databases/*.sqlite" with { type: "sqlite", embed: "false" } { +>"databases/*.sqlite" : Symbol("databases/*.sqlite", Decl(bun-sqlite.d.ts, 0, 0)) +>type : Symbol(type, Decl(bun-sqlite.d.ts, 0, 42)) +>embed : Symbol(embed, Decl(bun-sqlite.d.ts, 0, 58)) + + const database: { +>database : Symbol(database, Decl(bun-sqlite.d.ts, 1, 9)) + + storage: "external"; +>storage : Symbol(storage, Decl(bun-sqlite.d.ts, 1, 21)) + + filename: string; +>filename : Symbol(filename, Decl(bun-sqlite.d.ts, 2, 28)) + + }; + export default database; +>database : Symbol(database, Decl(bun-sqlite.d.ts, 1, 9)) +} + +declare module "*.sqlite" with { type: "sqlite", embed: "true" } { +>"*.sqlite" : Symbol("*.sqlite", Decl(bun-sqlite.d.ts, 6, 1)) +>type : Symbol(type, Decl(bun-sqlite.d.ts, 8, 32)) +>embed : Symbol(embed, Decl(bun-sqlite.d.ts, 8, 48)) + + const database: { +>database : Symbol(database, Decl(bun-sqlite.d.ts, 9, 9)) + + storage: "embedded"; +>storage : Symbol(storage, Decl(bun-sqlite.d.ts, 9, 21)) + + contents: Uint8Array; +>contents : Symbol(contents, Decl(bun-sqlite.d.ts, 10, 28)) +>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 3 more) + + }; + export default database; +>database : Symbol(database, Decl(bun-sqlite.d.ts, 9, 9)) +} + +=== /index.ts === +import badDatabase from "databases/app.sqlite" with { type: "sqlite" }; +>badDatabase : Symbol(badDatabase, Decl(index.ts, 0, 6)) + +import embeddedDatabase from "databases/app.sqlite" with { type: "sqlite", embed: "true" }; +>embeddedDatabase : Symbol(embeddedDatabase, Decl(index.ts, 1, 6)) + +const expectedExternalStorage: "external" = badDatabase.storage; +>expectedExternalStorage : Symbol(expectedExternalStorage, Decl(index.ts, 3, 5)) +>badDatabase : Symbol(badDatabase, Decl(index.ts, 0, 6)) + +const expectedEmbeddedStorage: "embedded" = embeddedDatabase.storage; +>expectedEmbeddedStorage : Symbol(expectedEmbeddedStorage, Decl(index.ts, 4, 5)) +>embeddedDatabase.storage : Symbol(storage, Decl(bun-sqlite.d.ts, 9, 21)) +>embeddedDatabase : Symbol(embeddedDatabase, Decl(index.ts, 1, 6)) +>storage : Symbol(storage, Decl(bun-sqlite.d.ts, 9, 21)) + +badDatabase.filename; +>badDatabase : Symbol(badDatabase, Decl(index.ts, 0, 6)) + +embeddedDatabase.contents; +>embeddedDatabase.contents : Symbol(contents, Decl(bun-sqlite.d.ts, 10, 28)) +>embeddedDatabase : Symbol(embeddedDatabase, Decl(index.ts, 1, 6)) +>contents : Symbol(contents, Decl(bun-sqlite.d.ts, 10, 28)) + diff --git a/tsc/testdata/baselines/reference/compiler/importAttributeType2.types b/tsc/testdata/baselines/reference/compiler/importAttributeType2.types new file mode 100644 index 0000000000000..976bdeddb70a3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/importAttributeType2.types @@ -0,0 +1,73 @@ +//// [tests/cases/compiler/importAttributeType2.ts] //// + +=== /bun-sqlite.d.ts === +declare module "databases/*.sqlite" with { type: "sqlite", embed: "false" } { +>"databases/*.sqlite" : typeof import("databases/*.sqlite") +>type : "sqlite" +>embed : "false" + + const database: { +>database : { storage: "external"; filename: string; } + + storage: "external"; +>storage : "external" + + filename: string; +>filename : string + + }; + export default database; +>database : { storage: "external"; filename: string; } +} + +declare module "*.sqlite" with { type: "sqlite", embed: "true" } { +>"*.sqlite" : typeof import("*.sqlite") +>type : "sqlite" +>embed : "true" + + const database: { +>database : { storage: "embedded"; contents: Uint8Array; } + + storage: "embedded"; +>storage : "embedded" + + contents: Uint8Array; +>contents : Uint8Array + + }; + export default database; +>database : { storage: "embedded"; contents: Uint8Array; } +} + +=== /index.ts === +import badDatabase from "databases/app.sqlite" with { type: "sqlite" }; +>badDatabase : any +>type : any + +import embeddedDatabase from "databases/app.sqlite" with { type: "sqlite", embed: "true" }; +>embeddedDatabase : { storage: "embedded"; contents: Uint8Array; } +>type : any +>embed : any + +const expectedExternalStorage: "external" = badDatabase.storage; +>expectedExternalStorage : "external" +>badDatabase.storage : any +>badDatabase : any +>storage : any + +const expectedEmbeddedStorage: "embedded" = embeddedDatabase.storage; +>expectedEmbeddedStorage : "embedded" +>embeddedDatabase.storage : "embedded" +>embeddedDatabase : { storage: "embedded"; contents: Uint8Array; } +>storage : "embedded" + +badDatabase.filename; +>badDatabase.filename : any +>badDatabase : any +>filename : any + +embeddedDatabase.contents; +>embeddedDatabase.contents : Uint8Array +>embeddedDatabase : { storage: "embedded"; contents: Uint8Array; } +>contents : Uint8Array + diff --git a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.errors.txt b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.errors.txt index c4990fd307206..c68e2d33ec857 100644 --- a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.errors.txt +++ b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.errors.txt @@ -1,4 +1,4 @@ -/index.ts(9,7): error TS2339: Property 'augmented' does not exist on type 'typeof import("*.asset")'. +/index.ts(11,7): error TS2339: Property 'augmented' does not exist on type 'typeof import("*.asset")'. ==== /a.d.ts (0 errors) ==== @@ -11,6 +11,11 @@ export const fromB: "b"; } +==== /c.d.ts (0 errors) ==== + declare module "*.asset" with {} { + export const fromAttributed: "attributed"; + } + ==== /augmentation.ts (0 errors) ==== export {}; @@ -22,11 +27,18 @@ import * as augmented from "augmented.asset"; augmented.fromA; augmented.fromB; + augmented.fromAttributed; augmented.augmented; import * as other from "other.asset"; other.fromA; other.fromB; + other.fromAttributed; other.augmented; ~~~~~~~~~ -!!! error TS2339: Property 'augmented' does not exist on type 'typeof import("*.asset")'. \ No newline at end of file +!!! error TS2339: Property 'augmented' does not exist on type 'typeof import("*.asset")'. + + import * as explicitlyEmpty from "other.asset" with {}; + explicitlyEmpty.fromA; + explicitlyEmpty.fromB; + explicitlyEmpty.fromAttributed; \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.symbols b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.symbols index 33d49a0392ee6..f68dd14689206 100644 --- a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.symbols +++ b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.symbols @@ -2,7 +2,7 @@ === /a.d.ts === declare module "*.asset" { ->"*.asset" : Symbol("*.asset", Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0)) +>"*.asset" : Symbol("*.asset", Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0), Decl(c.d.ts, 0, 0)) export const fromA: "a"; >fromA : Symbol(fromA, Decl(a.d.ts, 1, 16)) @@ -10,17 +10,25 @@ declare module "*.asset" { === /b.d.ts === declare module "*.asset" { ->"*.asset" : Symbol("*.asset", Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0)) +>"*.asset" : Symbol("*.asset", Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0), Decl(c.d.ts, 0, 0)) export const fromB: "b"; >fromB : Symbol(fromB, Decl(b.d.ts, 1, 16)) } +=== /c.d.ts === +declare module "*.asset" with {} { +>"*.asset" : Symbol("*.asset", Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0), Decl(c.d.ts, 0, 0)) + + export const fromAttributed: "attributed"; +>fromAttributed : Symbol(fromAttributed, Decl(c.d.ts, 1, 16)) +} + === /augmentation.ts === export {}; declare module "augmented.asset" { ->"augmented.asset" : Symbol("augmented.asset", Decl(augmentation.ts, 0, 10), Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0)) +>"augmented.asset" : Symbol("augmented.asset", Decl(augmentation.ts, 0, 10), Decl(a.d.ts, 0, 0), Decl(b.d.ts, 0, 0), Decl(c.d.ts, 0, 0)) export const augmented: "augmented"; >augmented : Symbol(augmented, Decl(augmentation.ts, 3, 16)) @@ -40,24 +48,52 @@ augmented.fromB; >augmented : Symbol(augmented, Decl(index.ts, 0, 6)) >fromB : Symbol(augmented.fromB, Decl(b.d.ts, 1, 16)) +augmented.fromAttributed; +>augmented.fromAttributed : Symbol(augmented.fromAttributed, Decl(c.d.ts, 1, 16)) +>augmented : Symbol(augmented, Decl(index.ts, 0, 6)) +>fromAttributed : Symbol(augmented.fromAttributed, Decl(c.d.ts, 1, 16)) + augmented.augmented; >augmented.augmented : Symbol(augmented.augmented, Decl(augmentation.ts, 3, 16)) >augmented : Symbol(augmented, Decl(index.ts, 0, 6)) >augmented : Symbol(augmented.augmented, Decl(augmentation.ts, 3, 16)) import * as other from "other.asset"; ->other : Symbol(other, Decl(index.ts, 5, 6)) +>other : Symbol(other, Decl(index.ts, 6, 6)) other.fromA; >other.fromA : Symbol(augmented.fromA, Decl(a.d.ts, 1, 16)) ->other : Symbol(other, Decl(index.ts, 5, 6)) +>other : Symbol(other, Decl(index.ts, 6, 6)) >fromA : Symbol(augmented.fromA, Decl(a.d.ts, 1, 16)) other.fromB; >other.fromB : Symbol(augmented.fromB, Decl(b.d.ts, 1, 16)) ->other : Symbol(other, Decl(index.ts, 5, 6)) +>other : Symbol(other, Decl(index.ts, 6, 6)) >fromB : Symbol(augmented.fromB, Decl(b.d.ts, 1, 16)) +other.fromAttributed; +>other.fromAttributed : Symbol(augmented.fromAttributed, Decl(c.d.ts, 1, 16)) +>other : Symbol(other, Decl(index.ts, 6, 6)) +>fromAttributed : Symbol(augmented.fromAttributed, Decl(c.d.ts, 1, 16)) + other.augmented; ->other : Symbol(other, Decl(index.ts, 5, 6)) +>other : Symbol(other, Decl(index.ts, 6, 6)) + +import * as explicitlyEmpty from "other.asset" with {}; +>explicitlyEmpty : Symbol(explicitlyEmpty, Decl(index.ts, 12, 6)) + +explicitlyEmpty.fromA; +>explicitlyEmpty.fromA : Symbol(augmented.fromA, Decl(a.d.ts, 1, 16)) +>explicitlyEmpty : Symbol(explicitlyEmpty, Decl(index.ts, 12, 6)) +>fromA : Symbol(augmented.fromA, Decl(a.d.ts, 1, 16)) + +explicitlyEmpty.fromB; +>explicitlyEmpty.fromB : Symbol(augmented.fromB, Decl(b.d.ts, 1, 16)) +>explicitlyEmpty : Symbol(explicitlyEmpty, Decl(index.ts, 12, 6)) +>fromB : Symbol(augmented.fromB, Decl(b.d.ts, 1, 16)) + +explicitlyEmpty.fromAttributed; +>explicitlyEmpty.fromAttributed : Symbol(augmented.fromAttributed, Decl(c.d.ts, 1, 16)) +>explicitlyEmpty : Symbol(explicitlyEmpty, Decl(index.ts, 12, 6)) +>fromAttributed : Symbol(augmented.fromAttributed, Decl(c.d.ts, 1, 16)) diff --git a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.types b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.types index 5be3b271f0dca..bba3ed4a4c163 100644 --- a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.types +++ b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleAugmentationMergedSymbol.types @@ -16,6 +16,14 @@ declare module "*.asset" { >fromB : "b" } +=== /c.d.ts === +declare module "*.asset" with {} { +>"*.asset" : typeof import("*.asset") + + export const fromAttributed: "attributed"; +>fromAttributed : "attributed" +} + === /augmentation.ts === export {}; @@ -40,6 +48,11 @@ augmented.fromB; >augmented : typeof augmented >fromB : "b" +augmented.fromAttributed; +>augmented.fromAttributed : "attributed" +>augmented : typeof augmented +>fromAttributed : "attributed" + augmented.augmented; >augmented.augmented : "augmented" >augmented : typeof augmented @@ -58,8 +71,31 @@ other.fromB; >other : typeof other >fromB : "b" +other.fromAttributed; +>other.fromAttributed : "attributed" +>other : typeof other +>fromAttributed : "attributed" + other.augmented; >other.augmented : any >other : typeof other >augmented : any +import * as explicitlyEmpty from "other.asset" with {}; +>explicitlyEmpty : typeof other + +explicitlyEmpty.fromA; +>explicitlyEmpty.fromA : "a" +>explicitlyEmpty : typeof other +>fromA : "a" + +explicitlyEmpty.fromB; +>explicitlyEmpty.fromB : "b" +>explicitlyEmpty : typeof other +>fromB : "b" + +explicitlyEmpty.fromAttributed; +>explicitlyEmpty.fromAttributed : "attributed" +>explicitlyEmpty : typeof other +>fromAttributed : "attributed" + diff --git a/tsc/testdata/tests/cases/compiler/importAttributeType2.ts b/tsc/testdata/tests/cases/compiler/importAttributeType2.ts new file mode 100644 index 0000000000000..0f0cd90ff7287 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/importAttributeType2.ts @@ -0,0 +1,31 @@ +// @strict: true +// @module: preserve +// @moduleResolution: bundler +// @noEmit: true + +// @filename: /bun-sqlite.d.ts +declare module "databases/*.sqlite" with { type: "sqlite", embed: "false" } { + const database: { + storage: "external"; + filename: string; + }; + export default database; +} + +declare module "*.sqlite" with { type: "sqlite", embed: "true" } { + const database: { + storage: "embedded"; + contents: Uint8Array; + }; + export default database; +} + +// @filename: /index.ts +import badDatabase from "databases/app.sqlite" with { type: "sqlite" }; +import embeddedDatabase from "databases/app.sqlite" with { type: "sqlite", embed: "true" }; + +const expectedExternalStorage: "external" = badDatabase.storage; +const expectedEmbeddedStorage: "embedded" = embeddedDatabase.storage; + +badDatabase.filename; +embeddedDatabase.contents; \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts b/tsc/testdata/tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts index 8615e8dcac0a2..97cf076e980ba 100644 --- a/tsc/testdata/tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts +++ b/tsc/testdata/tests/cases/compiler/patternAmbientModuleAugmentationMergedSymbol.ts @@ -13,6 +13,11 @@ declare module "*.asset" { export const fromB: "b"; } +// @filename: /c.d.ts +declare module "*.asset" with {} { + export const fromAttributed: "attributed"; +} + // @filename: /augmentation.ts export {}; @@ -24,9 +29,16 @@ declare module "augmented.asset" { import * as augmented from "augmented.asset"; augmented.fromA; augmented.fromB; +augmented.fromAttributed; augmented.augmented; import * as other from "other.asset"; other.fromA; other.fromB; -other.augmented; \ No newline at end of file +other.fromAttributed; +other.augmented; + +import * as explicitlyEmpty from "other.asset" with {}; +explicitlyEmpty.fromA; +explicitlyEmpty.fromB; +explicitlyEmpty.fromAttributed; \ No newline at end of file