Skip to content

Commit 659c141

Browse files
committed
Merge branch 'main' of https://github.com/microsoft/TypeScript into feat/51086
2 parents 566fb91 + eb9252e commit 659c141

File tree

176 files changed

+6685
-835
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

176 files changed

+6685
-835
lines changed

package-lock.json

Lines changed: 198 additions & 198 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/compiler/binder.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ import {
8484
getContainingClass,
8585
getEffectiveContainerForJSDocTemplateTag,
8686
getElementOrPropertyAccessName,
87+
getEmitModuleResolutionKind,
8788
getEmitScriptTarget,
8889
getEnclosingBlockScopeContainer,
8990
getErrorSpanForNode,
@@ -219,6 +220,7 @@ import {
219220
JSDocClassTag,
220221
JSDocEnumTag,
221222
JSDocFunctionType,
223+
JSDocOverloadTag,
222224
JSDocParameterTag,
223225
JSDocPropertyLikeTag,
224226
JSDocSignature,
@@ -235,6 +237,7 @@ import {
235237
ModifierFlags,
236238
ModuleBlock,
237239
ModuleDeclaration,
240+
ModuleResolutionKind,
238241
Mutable,
239242
NamespaceExportDeclaration,
240243
Node,
@@ -2964,6 +2967,8 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
29642967
case SyntaxKind.JSDocCallbackTag:
29652968
case SyntaxKind.JSDocEnumTag:
29662969
return (delayedTypeAliases || (delayedTypeAliases = [])).push(node as JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag);
2970+
case SyntaxKind.JSDocOverloadTag:
2971+
return bind((node as JSDocOverloadTag).typeExpression);
29672972
}
29682973
}
29692974

@@ -3520,6 +3525,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
35203525
if (!isBindingPattern(node.name)) {
35213526
const possibleVariableDecl = node.kind === SyntaxKind.VariableDeclaration ? node : node.parent.parent;
35223527
if (isInJSFile(node) &&
3528+
getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Bundler &&
35233529
isVariableDeclarationInitializedToBareOrAccessedRequire(possibleVariableDecl) &&
35243530
!getJSDocTypeTag(node) &&
35253531
!(getCombinedModifierFlags(node) & ModifierFlags.Export)

src/compiler/checker.ts

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ import {
139139
ElementFlags,
140140
EmitFlags,
141141
EmitHint,
142+
emitModuleKindIsNonNodeESM,
142143
EmitResolver,
143144
EmitTextWriter,
144145
emptyArray,
@@ -318,6 +319,7 @@ import {
318319
getResolutionModeOverrideForClause,
319320
getResolvedExternalModuleName,
320321
getResolvedModule,
322+
getResolveJsonModule,
321323
getRestParameterElementType,
322324
getRootDeclaration,
323325
getScriptTargetFeatures,
@@ -459,6 +461,7 @@ import {
459461
isConstructorTypeNode,
460462
isConstTypeReference,
461463
isDeclaration,
464+
isDeclarationFileName,
462465
isDeclarationName,
463466
isDeclarationReadonly,
464467
isDecorator,
@@ -547,6 +550,7 @@ import {
547550
isJSDocNullableType,
548551
isJSDocOptionalParameter,
549552
isJSDocOptionalType,
553+
isJSDocOverloadTag,
550554
isJSDocParameterTag,
551555
isJSDocPropertyLikeTag,
552556
isJSDocPropertyTag,
@@ -900,6 +904,7 @@ import {
900904
setTextRangePosEnd,
901905
setValueDeclaration,
902906
ShorthandPropertyAssignment,
907+
shouldAllowImportingTsExtension,
903908
shouldPreserveConstEnums,
904909
Signature,
905910
SignatureDeclaration,
@@ -4546,6 +4551,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
45464551
if (
45474552
namespace.valueDeclaration &&
45484553
isInJSFile(namespace.valueDeclaration) &&
4554+
getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Bundler &&
45494555
isVariableDeclaration(namespace.valueDeclaration) &&
45504556
namespace.valueDeclaration.initializer &&
45514557
isCommonJsRequire(namespace.valueDeclaration.initializer)
@@ -4730,6 +4736,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
47304736
(isModuleDeclaration(location) ? location : location.parent && isModuleDeclaration(location.parent) && location.parent.name === location ? location.parent : undefined)?.name ||
47314737
(isLiteralImportTypeNode(location) ? location : undefined)?.argument.literal;
47324738
const mode = contextSpecifier && isStringLiteralLike(contextSpecifier) ? getModeForUsageLocation(currentSourceFile, contextSpecifier) : currentSourceFile.impliedNodeFormat;
4739+
const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions);
47334740
const resolvedModule = getResolvedModule(currentSourceFile, moduleReference, mode);
47344741
const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule);
47354742
const sourceFile = resolvedModule
@@ -4740,11 +4747,28 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
47404747
if (resolutionDiagnostic) {
47414748
error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName);
47424749
}
4750+
4751+
if (resolvedModule.resolvedUsingTsExtension && isDeclarationFileName(moduleReference)) {
4752+
const importOrExport =
4753+
findAncestor(location, isImportDeclaration)?.importClause ||
4754+
findAncestor(location, or(isImportEqualsDeclaration, isExportDeclaration));
4755+
if (importOrExport && !importOrExport.isTypeOnly || findAncestor(location, isImportCall)) {
4756+
error(
4757+
errorNode,
4758+
Diagnostics.A_declaration_file_cannot_be_imported_without_import_type_Did_you_mean_to_import_an_implementation_file_0_instead,
4759+
getSuggestedImportSource(Debug.checkDefined(tryExtractTSExtension(moduleReference))));
4760+
}
4761+
}
4762+
else if (resolvedModule.resolvedUsingTsExtension && !shouldAllowImportingTsExtension(compilerOptions, currentSourceFile.fileName)) {
4763+
const tsExtension = Debug.checkDefined(tryExtractTSExtension(moduleReference));
4764+
error(errorNode, Diagnostics.An_import_path_can_only_end_with_a_0_extension_when_allowImportingTsExtensions_is_enabled, tsExtension);
4765+
}
4766+
47434767
if (sourceFile.symbol) {
47444768
if (resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) {
47454769
errorOnImplicitAnyModule(/*isError*/ false, errorNode, resolvedModule, moduleReference);
47464770
}
4747-
if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) {
4771+
if (moduleResolutionKind === ModuleResolutionKind.Node16 || moduleResolutionKind === ModuleResolutionKind.NodeNext) {
47484772
const isSyncImport = (currentSourceFile.impliedNodeFormat === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) || !!findAncestor(location, isImportEqualsDeclaration);
47494773
const overrideClauseHost = findAncestor(location, l => isImportTypeNode(l) || isExportDeclaration(l) || isImportDeclaration(l)) as ImportTypeNode | ImportDeclaration | ExportDeclaration | undefined;
47504774
const overrideClause = overrideClauseHost && isImportTypeNode(overrideClauseHost) ? overrideClauseHost.assertions?.assertClause : overrideClauseHost?.assertClause;
@@ -4852,25 +4876,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
48524876
else {
48534877
const tsExtension = tryExtractTSExtension(moduleReference);
48544878
const isExtensionlessRelativePathImport = pathIsRelative(moduleReference) && !hasExtension(moduleReference);
4855-
const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions);
48564879
const resolutionIsNode16OrNext = moduleResolutionKind === ModuleResolutionKind.Node16 ||
48574880
moduleResolutionKind === ModuleResolutionKind.NodeNext;
48584881
if (tsExtension) {
4859-
const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
4860-
const importSourceWithoutExtension = removeExtension(moduleReference, tsExtension);
4861-
let replacedImportSource = importSourceWithoutExtension;
4862-
/**
4863-
* Direct users to import source with .js extension if outputting an ES module.
4864-
* @see https://github.com/microsoft/TypeScript/issues/42151
4865-
*/
4866-
if (moduleKind >= ModuleKind.ES2015) {
4867-
replacedImportSource += tsExtension === Extension.Mts ? ".mjs" : tsExtension === Extension.Cts ? ".cjs" : ".js";
4868-
}
4869-
error(errorNode, diag, tsExtension, replacedImportSource);
4870-
}
4871-
else if (!compilerOptions.resolveJsonModule &&
4882+
errorOnTSExtensionImport(tsExtension);
4883+
}
4884+
else if (!getResolveJsonModule(compilerOptions) &&
48724885
fileExtensionIs(moduleReference, Extension.Json) &&
4873-
getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Classic &&
4886+
moduleResolutionKind !== ModuleResolutionKind.Classic &&
48744887
hasJsonModuleEmitEnabled(compilerOptions)) {
48754888
error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference);
48764889
}
@@ -4892,6 +4905,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
48924905
}
48934906
}
48944907
return undefined;
4908+
4909+
function errorOnTSExtensionImport(tsExtension: string) {
4910+
const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
4911+
error(errorNode, diag, tsExtension, getSuggestedImportSource(tsExtension));
4912+
}
4913+
4914+
function getSuggestedImportSource(tsExtension: string) {
4915+
const importSourceWithoutExtension = removeExtension(moduleReference, tsExtension);
4916+
/**
4917+
* Direct users to import source with .js extension if outputting an ES module.
4918+
* @see https://github.com/microsoft/TypeScript/issues/42151
4919+
*/
4920+
if (emitModuleKindIsNonNodeESM(moduleKind) || mode === ModuleKind.ESNext) {
4921+
return importSourceWithoutExtension + (tsExtension === Extension.Mts ? ".mjs" : tsExtension === Extension.Cts ? ".cjs" : ".js");
4922+
}
4923+
return importSourceWithoutExtension;
4924+
}
48954925
}
48964926

48974927
function errorOnImplicitAnyModule(isError: boolean, errorNode: Node, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string): void {
@@ -14244,6 +14274,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1424414274
continue;
1424514275
}
1424614276
}
14277+
if (isInJSFile(decl) && decl.jsDoc) {
14278+
let hasJSDocOverloads = false;
14279+
for (const node of decl.jsDoc) {
14280+
if (node.tags) {
14281+
for (const tag of node.tags) {
14282+
if (isJSDocOverloadTag(tag)) {
14283+
result.push(getSignatureFromDeclaration(tag.typeExpression));
14284+
hasJSDocOverloads = true;
14285+
}
14286+
}
14287+
}
14288+
}
14289+
if (hasJSDocOverloads) {
14290+
continue;
14291+
}
14292+
}
1424714293
// If this is a function or method declaration, get the signature from the @type tag for the sake of optional parameters.
1424814294
// Exclude contextually-typed kinds because we already apply the @type tag to the context, plus applying it here to the initializer would supress checks that the two are compatible.
1424914295
result.push(
@@ -33303,7 +33349,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3330333349
}
3330433350

3330533351
// In JavaScript files, calls to any identifier 'require' are treated as external module imports
33306-
if (isInJSFile(node) && isCommonJsRequire(node)) {
33352+
if (isInJSFile(node) && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Bundler && isCommonJsRequire(node)) {
3330733353
return resolveExternalModuleTypeByLiteral(node.arguments![0] as StringLiteral);
3330833354
}
3330933355

@@ -42715,6 +42761,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4271542761
// Import equals declaration is deprecated in es6 or above
4271642762
grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
4271742763
}
42764+
else if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Bundler) {
42765+
grammarErrorOnNode(node, Diagnostics.Import_assignment_is_not_allowed_when_moduleResolution_is_set_to_bundler_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
42766+
}
4271842767
}
4271942768
}
4272042769
}
@@ -42937,6 +42986,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4293742986
// system modules does not support export assignment
4293842987
grammarErrorOnNode(node, Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system);
4293942988
}
42989+
else if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Bundler) {
42990+
grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_moduleResolution_is_set_to_bundler_Consider_using_export_default_or_another_module_format_instead);
42991+
}
4294042992
}
4294142993
}
4294242994

@@ -44033,7 +44085,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4403344085
// 4). type A = import("./f/*gotToDefinitionHere*/oo")
4403444086
if ((isExternalModuleImportEqualsDeclaration(node.parent.parent) && getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) ||
4403544087
((node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration) && (node.parent as ImportDeclaration).moduleSpecifier === node) ||
44036-
((isInJSFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || isImportCall(node.parent)) ||
44088+
((isInJSFile(node) && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Bundler && isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || isImportCall(node.parent)) ||
4403744089
(isLiteralTypeNode(node.parent) && isLiteralImportTypeNode(node.parent.parent) && node.parent.parent.argument === node.parent)
4403844090
) {
4403944091
return resolveExternalModuleName(node, node as LiteralExpression, ignoreErrors);
@@ -47339,4 +47391,4 @@ class SymbolTrackerImpl implements SymbolTracker {
4733947391
private onDiagnosticReported() {
4734047392
this.context.reportedDiagnostic = true;
4734147393
}
47342-
}
47394+
}

src/compiler/commandLineParser.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
965965
classic: ModuleResolutionKind.Classic,
966966
node16: ModuleResolutionKind.Node16,
967967
nodenext: ModuleResolutionKind.NodeNext,
968+
bundler: ModuleResolutionKind.Bundler,
968969
})),
969970
affectsModuleResolution: true,
970971
paramType: Diagnostics.STRATEGY,
@@ -1081,6 +1082,41 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
10811082
category: Diagnostics.Modules,
10821083
description: Diagnostics.List_of_file_name_suffixes_to_search_when_resolving_a_module,
10831084
},
1085+
{
1086+
name: "allowImportingTsExtensions",
1087+
type: "boolean",
1088+
affectsModuleResolution: true,
1089+
category: Diagnostics.Modules,
1090+
description: Diagnostics.Allow_imports_to_include_TypeScript_file_extensions_Requires_moduleResolution_bundler_and_either_noEmit_or_emitDeclarationOnly_to_be_set,
1091+
defaultValueDescription: false,
1092+
},
1093+
{
1094+
name: "resolvePackageJsonExports",
1095+
type: "boolean",
1096+
affectsModuleResolution: true,
1097+
category: Diagnostics.Modules,
1098+
description: Diagnostics.Use_the_package_json_exports_field_when_resolving_package_imports,
1099+
defaultValueDescription: Diagnostics.true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false,
1100+
},
1101+
{
1102+
name: "resolvePackageJsonImports",
1103+
type: "boolean",
1104+
affectsModuleResolution: true,
1105+
category: Diagnostics.Modules,
1106+
description: Diagnostics.Use_the_package_json_imports_field_when_resolving_imports,
1107+
defaultValueDescription: Diagnostics.true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false,
1108+
},
1109+
{
1110+
name: "customConditions",
1111+
type: "list",
1112+
element: {
1113+
name: "condition",
1114+
type: "string",
1115+
},
1116+
affectsModuleResolution: true,
1117+
category: Diagnostics.Modules,
1118+
description: Diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports,
1119+
},
10841120

10851121
// Source Maps
10861122
{

0 commit comments

Comments
 (0)