Find and parse the tsconfig.json file from a directory path
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Module path resolution functionality for resolving import specifiers using TypeScript's path mapping configuration from compilerOptions.paths and baseUrl.
Creates a path matcher function that resolves module specifiers according to TypeScript's path mapping rules.
/**
* Creates a path matcher function based on tsconfig paths configuration
* @param tsconfig - The parsed tsconfig result from getTsconfig or parseTsconfig
* @returns Path matcher function or null if no paths/baseUrl configuration exists
*/
function createPathsMatcher(
tsconfig: TsConfigResult
): ((specifier: string) => string[]) | null;
/**
* Function that resolves a module specifier to possible file paths
* @param specifier - The import specifier to resolve (e.g., "@/utils", "lodash")
* @returns Array of possible absolute file paths to check, empty if no matches
*/
type PathsMatcher = (specifier: string) => string[];Usage Examples:
import { getTsconfig, createPathsMatcher, type TsConfigResult } from "get-tsconfig";
const tsconfig = getTsconfig("./my-project");
const pathsMatcher = createPathsMatcher(tsconfig);
if (pathsMatcher) {
// Resolve path-mapped imports
const utilsPaths = pathsMatcher("@/utils"); // ["/project/src/utils"]
const componentPaths = pathsMatcher("@/components/Button"); // ["/project/src/components/Button"]
// Relative imports return empty array (handled by normal resolution)
const relativePaths = pathsMatcher("./local-file"); // []
// Non-matching specifiers fall back to baseUrl resolution
const basePaths = pathsMatcher("some-module"); // ["/project/src/some-module"] if baseUrl is set
}Path resolution works with TypeScript's compilerOptions.paths and compilerOptions.baseUrl settings:
// Example tsconfig.json with path mapping
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@/*": ["./utils/*", "./lib/*"],
"@components/*": ["./components/*"],
"~/*": ["../shared/*"]
}
}
}The path matcher implements TypeScript's module resolution logic:
* wildcards, preferring longer prefixesPattern Matching Rules:
* wildcard* wildcard// Given tsconfig paths configuration:
// "@lib/*": ["./libraries/*", "./vendor/*"]
const pathsMatcher = createPathsMatcher(tsconfig);
// Resolves "@lib/utils" to:
const paths = pathsMatcher("@lib/utils");
// Returns: ["/project/src/libraries/utils", "/project/src/vendor/utils"]
// The "*" in the pattern matches "utils"
// The "*" in substitutions is replaced with "utils"When no path patterns match, baseUrl provides fallback resolution:
// Given tsconfig with baseUrl: "./src" and no matching paths
const pathsMatcher = createPathsMatcher(tsconfig);
// Non-relative specifier with baseUrl fallback
const paths = pathsMatcher("helpers/format");
// Returns: ["/project/src/helpers/format"]Common integration pattern with custom module resolution systems:
import { getTsconfig, createPathsMatcher, type TsConfigResult } from "get-tsconfig";
import { existsSync } from "fs";
import { resolve } from "path";
function resolveModule(specifier: string, fromFile: string): string | null {
const tsconfig = getTsconfig(fromFile);
const pathsMatcher = createPathsMatcher(tsconfig);
if (pathsMatcher) {
const candidatePaths = pathsMatcher(specifier);
// Try each candidate path with common extensions
for (const candidatePath of candidatePaths) {
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.d.ts'];
for (const ext of extensions) {
const fullPath = candidatePath + ext;
if (existsSync(fullPath)) {
return fullPath;
}
}
// Try index files
const indexPath = resolve(candidatePath, 'index.ts');
if (existsSync(indexPath)) {
return indexPath;
}
}
}
// Fallback to standard Node.js resolution
return null;
}get-tsconfig handles TypeScript's implicit baseUrl behavior when paths are specified without baseUrl:
// tsconfig.json with paths but no explicit baseUrl
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}The library automatically uses the tsconfig directory as an implicit baseUrl for path resolution.
The path matcher handles various edge cases gracefully:
null if no paths or baseUrl are configuredimport { createPathsMatcher } from "get-tsconfig";
const pathsMatcher = createPathsMatcher(tsconfig);
if (pathsMatcher === null) {
console.log("No path mapping configuration found");
} else {
// Safe to use path matcher
const paths = pathsMatcher("@/utils");
}Example integration with bundlers and build tools:
import { getTsconfig, createPathsMatcher, type TsConfigResult } from "get-tsconfig";
function createResolver(projectRoot: string) {
const tsconfig = getTsconfig(projectRoot);
const pathsMatcher = createPathsMatcher(tsconfig);
return {
resolve(specifier: string, importer: string): string[] {
if (pathsMatcher) {
const mappedPaths = pathsMatcher(specifier);
if (mappedPaths.length > 0) {
return mappedPaths;
}
}
// Fallback to standard resolution
return [specifier];
}
};
}