Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,7 @@ import {
TypeReferenceNode,
TypeReferenceSerializationKind,
TypeReferenceType,
typesIncludesWildcard,
TypeVariable,
unescapeLeadingUnderscores,
UnionOrIntersectionType,
Expand Down Expand Up @@ -27628,27 +27629,27 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
case "console":
return Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom;
case "$":
return compilerOptions.types
? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig
: Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery;
return typesIncludesWildcard(compilerOptions.types)
? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery
: Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig;
case "describe":
case "suite":
case "it":
case "test":
return compilerOptions.types
? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig
: Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha;
return typesIncludesWildcard(compilerOptions.types)
? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha
: Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig;
case "process":
case "require":
case "Buffer":
case "module":
return compilerOptions.types
? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig
: Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode;
return typesIncludesWildcard(compilerOptions.types)
? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode
: Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig;
case "Bun":
return compilerOptions.types
? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_Bun_Try_npm_i_save_dev_types_Slashbun_and_then_add_bun_to_the_types_field_in_your_tsconfig
: Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_Bun_Try_npm_i_save_dev_types_Slashbun;
return typesIncludesWildcard(compilerOptions.types)
? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_Bun_Try_npm_i_save_dev_types_Slashbun
: Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_Bun_Try_npm_i_save_dev_types_Slashbun_and_then_add_bun_to_the_types_field_in_your_tsconfig;
case "Map":
case "Set":
case "Promise":
Expand Down
32 changes: 23 additions & 9 deletions src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ import {
emptyArray,
endsWith,
ensureTrailingDirectorySeparator,
equateValues,
every,
Extension,
extensionIsTS,
fileExtensionIs,
fileExtensionIsOneOf,
filter,
firstDefined,
flatten,
forEach,
forEachAncestorDirectory,
formatMessage,
Expand Down Expand Up @@ -799,6 +801,14 @@ export function resolvePackageNameToPackageJson(
});
}

/**
* Returns true if the types compiler option includes the "*" wildcard.
* @internal
*/
export function typesIncludesWildcard(types: readonly string[] | undefined): boolean {
return types?.includes("*") ?? false;
}

/**
* Given a set of options, returns the set of type directive names
* that should be included for this program automatically.
Expand All @@ -808,13 +818,17 @@ export function resolvePackageNameToPackageJson(
* this list is only the set of defaults that are implicitly included.
*/
export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] {
// Use explicit type list from tsconfig.json
if (options.types) {
// Default to [] if nothing specified
if (options.types === undefined) {
return emptyArray;
}

if (!typesIncludesWildcard(options.types)) {
// No wildcard, no need to iterate anything
return options.types;
}

// Walk the primary type lookup locations
const result: string[] = [];
const wildcardMatches: string[] = [];
if (host.directoryExists && host.getDirectories) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also need to fix FileIncludeKind.AutomaticTypeDirectiveFile for explainFiles and fileIncludeReasonToRelatedInformation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5b122ff. Updated FileIncludeKind.AutomaticTypeDirectiveFile handling in both programDiagnostics.ts and watch.ts to always use the "specified in compilerOptions" messages (removed implicit type library messages since types must now be explicit).

const typeRoots = getEffectiveTypeRoots(options, host);
if (typeRoots) {
Expand All @@ -829,19 +843,19 @@ export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: M
const isNotNeededPackage = host.fileExists(packageJsonPath) && (readJson(packageJsonPath, host) as PackageJson).typings === null;
if (!isNotNeededPackage) {
const baseFileName = getBaseFileName(normalized);

// At this stage, skip results with leading dot.
if (baseFileName.charCodeAt(0) !== CharacterCodes.dot) {
// Return just the type directive names
result.push(baseFileName);
wildcardMatches.push(baseFileName);
}
}
}
}
}
}
}
return result;

// Order potentially matters in program construction, so substitute
// in the wildcard in the position it was specified in the types array
return deduplicate(flatten(options.types.map(t => t === "*" ? wildcardMatches : t)), equateValues);
}

export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, NonRelativeNameResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/programDiagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
removeSuffix,
SourceFile,
TsConfigSourceFile,
typesIncludesWildcard,
} from "./_namespaces/ts.js";

interface FileReasonToChainCache {
Expand Down Expand Up @@ -400,7 +401,7 @@ export function createProgramDiagnostics(getCompilerOptionsObjectLiteralSyntax:
) :
undefined;
case FileIncludeKind.AutomaticTypeDirectiveFile:
if (!options.types) return undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should check for a wildcard, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 7f169c1. Now returns early when wildcard is present using options.types?.includes("*").

if (typesIncludesWildcard(options.types)) return undefined;
configFileNode = getOptionsSyntaxByArrayElementValue(getCompilerOptionsObjectLiteralSyntax(), "types", reason.typeReference);
message = Diagnostics.File_is_entry_point_of_type_library_specified_here;
break;
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/resolutionCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import {
startsWith,
StringLiteralLike,
trace,
typesIncludesWildcard,
updateResolutionField,
WatchDirectoryFlags,
} from "./_namespaces/ts.js";
Expand Down Expand Up @@ -1667,7 +1668,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
*/
function updateTypeRootsWatch() {
const options = resolutionHost.getCompilationSettings();
if (options.types) {
if (options.types && !typesIncludesWildcard(options.types)) {
// No need to do any watch since resolution cache is going to handle the failed lookups
// for the types added by this
closeTypeRootsWatch();
Expand Down
11 changes: 6 additions & 5 deletions src/compiler/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import {
sourceMapCommentRegExpDontCareLineStart,
sys,
System,
typesIncludesWildcard,
WatchCompilerHost,
WatchCompilerHostOfConfigFile,
WatchCompilerHostOfFilesAndCompilerOptions,
Expand Down Expand Up @@ -529,13 +530,13 @@ export function fileIncludeReasonToDiagnostics(program: Program, reason: FileInc
options.outFile ? "--outFile" : "--out",
);
case FileIncludeKind.AutomaticTypeDirectiveFile: {
const messageAndArgs: DiagnosticAndArguments = options.types ?
const messageAndArgs: DiagnosticAndArguments = typesIncludesWildcard(options.types) ?
reason.packageId ?
[Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions_with_packageId_1, reason.typeReference, packageIdToString(reason.packageId)] :
[Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions, reason.typeReference] :
[Diagnostics.Entry_point_for_implicit_type_library_0_with_packageId_1, reason.typeReference, packageIdToString(reason.packageId)] :
[Diagnostics.Entry_point_for_implicit_type_library_0, reason.typeReference] :
reason.packageId ?
[Diagnostics.Entry_point_for_implicit_type_library_0_with_packageId_1, reason.typeReference, packageIdToString(reason.packageId)] :
[Diagnostics.Entry_point_for_implicit_type_library_0, reason.typeReference];
[Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions_with_packageId_1, reason.typeReference, packageIdToString(reason.packageId)] :
[Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions, reason.typeReference];

return chainDiagnosticMessages(/*details*/ undefined, ...messageAndArgs);
}
Expand Down
3 changes: 2 additions & 1 deletion src/jsTyping/jsTyping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
some,
toFileNameLowerCase,
TypeAcquisition,
typesIncludesWildcard,
Version,
versionMajorMinor,
} from "./_namespaces/ts.js";
Expand Down Expand Up @@ -133,7 +134,7 @@ export function discoverTypings(
const exclude = typeAcquisition.exclude || [];

// Directories to search for package.json, bower.json and other typing information
if (!compilerOptions.types) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be types?.includes("*")? (perhaps this concept needs a helper everyone can use?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 7f169c1. Changed to use optional chaining: compilerOptions.types?.includes("*").

if (typesIncludesWildcard(compilerOptions.types)) {
const possibleSearchDirs = new Set(fileNames.map(getDirectoryPath));
possibleSearchDirs.add(projectRootPath);
possibleSearchDirs.forEach(searchDir => {
Expand Down
4 changes: 2 additions & 2 deletions src/testRunner/unittests/tsbuild/moduleResolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ describe("unittests:: tsbuild:: moduleResolution:: handles the modules and optio
TestServerHost.createWatchedSystem({
"/home/src/workspaces/project/packages/pkg1_index.ts": `export const theNum: TheNum = "type1";`,
"/home/src/workspaces/project/packages/pkg1.tsconfig.json": jsonToReadableText({
compilerOptions: { composite: true, typeRoots: ["./typeroot1"] },
compilerOptions: { composite: true, typeRoots: ["./typeroot1"], types: ["sometype"] },
files: ["./pkg1_index.ts"],
}),
"/home/src/workspaces/project/packages/typeroot1/sometype/index.d.ts": dedent`declare type TheNum = "type1";`,
"/home/src/workspaces/project/packages/pkg2_index.ts": `export const theNum: TheNum2 = "type2";`,
"/home/src/workspaces/project/packages/pkg2.tsconfig.json": jsonToReadableText({
compilerOptions: { composite: true, typeRoots: ["./typeroot2"] },
compilerOptions: { composite: true, typeRoots: ["./typeroot2"], types: ["sometype"] },
files: ["./pkg2_index.ts"],
}),
"/home/src/workspaces/project/packages/typeroot2/sometype/index.d.ts": dedent`declare type TheNum2 = "type2";`,
Expand Down
4 changes: 2 additions & 2 deletions src/testRunner/unittests/tsc/incremental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ declare global {
"/home/src/workspaces/project/node_modules/react/jsx-runtime.js": "export {}", // js needs to be present so there's a resolution result
"/home/src/workspaces/project/node_modules/@types/react/index.d.ts": getJsxLibraryContent(), // doesn't contain a jsx-runtime definition
"/home/src/workspaces/project/src/index.tsx": `export const App = () => <div propA={true}></div>;`,
"/home/src/workspaces/project/tsconfig.json": jsonToReadableText({ compilerOptions: { module: "commonjs", jsx: "react-jsx", incremental: true, jsxImportSource: "react" } }),
"/home/src/workspaces/project/tsconfig.json": jsonToReadableText({ compilerOptions: { module: "commonjs", jsx: "react-jsx", incremental: true, jsxImportSource: "react", types: ["react"] } }),
}),
commandLineArgs: ts.emptyArray,
});
Expand All @@ -201,7 +201,7 @@ declare global {
"/home/src/workspaces/project/node_modules/react/jsx-runtime.js": "export {}", // js needs to be present so there's a resolution result
"/home/src/workspaces/project/node_modules/@types/react/index.d.ts": getJsxLibraryContent(), // doesn't contain a jsx-runtime definition
"/home/src/workspaces/project/src/index.tsx": `export const App = () => <div propA={true}></div>;`,
"/home/src/workspaces/project/tsconfig.json": jsonToReadableText({ compilerOptions: { module: "commonjs", jsx: "react-jsx", incremental: true, jsxImportSource: "react" } }),
"/home/src/workspaces/project/tsconfig.json": jsonToReadableText({ compilerOptions: { module: "commonjs", jsx: "react-jsx", incremental: true, jsxImportSource: "react", types: ["react"] } }),
}),
commandLineArgs: ["--strict"],
});
Expand Down
5 changes: 4 additions & 1 deletion src/testRunner/unittests/tscWatch/resolutionCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ describe("unittests:: tscWatch:: resolutionCache:: tsc-watch module resolution c
TestServerHost.createWatchedSystem([{
path: "/users/username/projects/project/foo.ts",
content: `import * as fs from "fs";`,
}, {
path: "/users/username/projects/project/tsconfig.json",
content: jsonToReadableText({ compilerOptions: { types: ["*"] } }),
}], { currentDirectory: "/users/username/projects/project" }),
edits: [
{
Expand Down Expand Up @@ -565,7 +568,7 @@ declare namespace NodeJS {
};
const tsconfig: File = {
path: `/user/username/projects/myproject/tsconfig.json`,
content: "{}",
content: jsonToReadableText({ compilerOptions: { types: ["*"] } }),
};
const { nodeAtTypesIndex, nodeAtTypesBase, nodeAtTypes36Base, nodeAtTypesGlobals } = getNodeAtTypes();
return TestServerHost.createWatchedSystem(
Expand Down
2 changes: 1 addition & 1 deletion src/testRunner/unittests/tsserver/configuredProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1177,7 +1177,7 @@ describe("unittests:: tsserver:: configuredProjects:: non-existing directories l
const config = {
path: "/user/username/projects/project/a/tsconfig.json",
content: jsonToReadableText({
compiler: {},
compilerOptions: { types: ["typings"] },
files: [],
}),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { value1 } from "../node_modules/.cache/someFile.d.ts";`,
};
const tsconfig: File = {
path: "/home/src/projects/project/tsconfig.json",
content: "{}",
content: jsonToReadableText({ compilerOptions: { types: ["node"] } }),
};
const host = TestServerHost.createServerHost([file1, file2, file3, file3, file4, nodeModulesFile1, nodeModulesFile2, tsconfig]);
const session = new TestSession(host);
Expand Down
2 changes: 1 addition & 1 deletion src/testRunner/unittests/tsserver/resolutionCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe("unittests:: tsserver:: resolutionCache:: tsserverProjectSystem watchin
const tsconfig = {
path: "/users/username/projects/project/tsconfig.json",
content: jsonToReadableText({
compilerOptions: {},
compilerOptions: { types: ["*"] },
exclude: ["node_modules"],
}),
};
Expand Down
2 changes: 1 addition & 1 deletion src/testRunner/unittests/tsserver/typingsInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ describe("unittests:: tsserver:: typingsInstaller:: General functionality", () =
});
openExternalProjectForSession({
projectFileName,
options: {},
options: { types: ["*"] },
rootFiles: [toExternalFile(appJs.path)],
typeAcquisition: { enable: true, include: ["node"] },
}, session);
Expand Down
12 changes: 6 additions & 6 deletions tests/baselines/reference/anonymousModules.errors.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
anonymousModules.ts(1,1): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
anonymousModules.ts(1,1): error TS2591: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
anonymousModules.ts(1,8): error TS1437: Namespace must be given a name.
anonymousModules.ts(4,2): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
anonymousModules.ts(4,2): error TS2591: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
anonymousModules.ts(4,9): error TS1437: Namespace must be given a name.
anonymousModules.ts(10,2): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
anonymousModules.ts(10,2): error TS2591: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
anonymousModules.ts(10,9): error TS1437: Namespace must be given a name.


==== anonymousModules.ts (6 errors) ====
module {
~~~~~~
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
!!! error TS2591: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
~
!!! error TS1437: Namespace must be given a name.
export var foo = 1;

module {
~~~~~~
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
!!! error TS2591: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
~
!!! error TS1437: Namespace must be given a name.
export var bar = 1;
Expand All @@ -26,7 +26,7 @@ anonymousModules.ts(10,9): error TS1437: Namespace must be given a name.

module {
~~~~~~
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
!!! error TS2591: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
~
!!! error TS1437: Namespace must be given a name.
var x = bar;
Expand Down
Loading