You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With baseUrl removed and a single catch-all paths entry (e.g. "*": ["./src/*"]),
tsc-alias leaves all matching imports unchanged. This is the exact configuration
the TypeScript team recommends as the replacement for baseUrl in TypeScript 7
(microsoft/TypeScript#62207), so it is likely to become a common setup.
Related: #255 (closed) and #134 describe the broader no-baseUrlbasePath
miscomputation. This report is narrower and, I think, more actionable: it pins
down why the catch-all specifically produces no output, with source references.
Environment
tsc-alias: 1.9.2 (latest)
TypeScript: 7.0.2 (confirmed; tsc itself compiles the catch-all config without
error, so TS7 resolves "*": ["./src/*"] fine and only tsc-alias fails to
rewrite the emitted import). Also reproduces on TypeScript 6.x.
Config: module/moduleResolution: NodeNext, rootDir: src, outDir: dist,
no baseUrl.
Actualdist/index.js (unchanged, fails at runtime under Node):
import{NAME}from"config.js";
Root cause
Two things combine in 1.9.2:
The catch-all alias is dropped from the trie. In dist/utils/trie.js, buildAliasTrie computes prefix = alias.replace(/\*$/, ""), which is ""
for a bare "*", and then only adds the alias when if (alias.prefix) is
truthy. An empty prefix is falsy, so "*" is silently skipped and the default
replacer never has anything to match.
The implicit-baseUrl branch never sets baseUrl. In dist/helpers/config.js, when baseUrl is absent but paths exist, the else if branch rewrites each path relative to rootDir ("./src/*" becomes "*") but does not assign config.baseUrl = rootDir. baseUrl therefore
defaults to "", so the built-in base-url replacer stays disabled
(enabled: !!config.baseUrl in dist/helpers/replacers.js) and cannot pick up
the bare specifier either.
Net effect: neither the default (trie) replacer nor the base-url replacer handles
the catch-all, so nothing is rewritten.
Suggested fix direction
Either (or both):
Treat an empty-prefix "*" as a valid catch-all in buildAliasTrie (match any
non-relative specifier, resolving the target against outDir), rather than
discarding it.
In the implicit-baseUrl branch of loadConfig, set config.baseUrl = rootDir
(as PR fix: support ts 6 implicit baseURL #259 originally did) so the existing base-url replacer activates and
resolves bare specifiers against outDir by file existence.
Happy to open a PR with a projects/projectNN test case mirroring the TS7
catch-all config if a maintainer confirms this direction fits the current rework
in #262.
Workaround for anyone stuck today
A tiny custom replacer reproduces the base-url behavior without needing baseUrl.
It rewrites any bare specifier that resolves to an emitted file under outDir, and
leaves node_modules imports alone:
Wire it in: tsc-alias -p tsconfig.json --replacer ./tsc-alias.replacer.cjs. Note
this relies on specifiers carrying explicit extensions (config.js, utils/index.js), which is the norm under NodeNext.
Summary
With
baseUrlremoved and a single catch-allpathsentry (e.g."*": ["./src/*"]),tsc-alias leaves all matching imports unchanged. This is the exact configuration
the TypeScript team recommends as the replacement for
baseUrlin TypeScript 7(microsoft/TypeScript#62207), so it is likely to become a common setup.
Related: #255 (closed) and #134 describe the broader no-
baseUrlbasePathmiscomputation. This report is narrower and, I think, more actionable: it pins
down why the catch-all specifically produces no output, with source references.
Environment
tscitself compiles the catch-all config withouterror, so TS7 resolves
"*": ["./src/*"]fine and only tsc-alias fails torewrite the emitted import). Also reproduces on TypeScript 6.x.
module/moduleResolution: NodeNext,rootDir: src,outDir: dist,no
baseUrl.Minimal reproduction
tsconfig.json:{ "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext", "target": "ESNext", "rootDir": "src", "outDir": "dist", "paths": { "*": ["./src/*"], }, }, "include": ["src/**/*"], }src/config.ts:src/index.ts:Run:
tsc && tsc-alias -p tsconfig.jsonExpected
dist/index.js:Actual
dist/index.js(unchanged, fails at runtime under Node):Root cause
Two things combine in 1.9.2:
The catch-all alias is dropped from the trie. In
dist/utils/trie.js,buildAliasTriecomputesprefix = alias.replace(/\*$/, ""), which is""for a bare
"*", and then only adds the alias whenif (alias.prefix)istruthy. An empty prefix is falsy, so
"*"is silently skipped and the defaultreplacer never has anything to match.
The implicit-
baseUrlbranch never setsbaseUrl. Indist/helpers/config.js, whenbaseUrlis absent butpathsexist, theelse ifbranch rewrites each path relative torootDir("./src/*"becomes"*") but does not assignconfig.baseUrl = rootDir.baseUrlthereforedefaults to
"", so the built-inbase-urlreplacer stays disabled(
enabled: !!config.baseUrlindist/helpers/replacers.js) and cannot pick upthe bare specifier either.
Net effect: neither the default (trie) replacer nor the base-url replacer handles
the catch-all, so nothing is rewritten.
Suggested fix direction
Either (or both):
"*"as a valid catch-all inbuildAliasTrie(match anynon-relative specifier, resolving the target against
outDir), rather thandiscarding it.
baseUrlbranch ofloadConfig, setconfig.baseUrl = rootDir(as PR fix: support ts 6 implicit baseURL #259 originally did) so the existing
base-urlreplacer activates andresolves bare specifiers against
outDirby file existence.Happy to open a PR with a
projects/projectNNtest case mirroring the TS7catch-all config if a maintainer confirms this direction fits the current rework
in #262.
Workaround for anyone stuck today
A tiny custom replacer reproduces the base-url behavior without needing
baseUrl.It rewrites any bare specifier that resolves to an emitted file under
outDir, andleaves
node_modulesimports alone:Wire it in:
tsc-alias -p tsconfig.json --replacer ./tsc-alias.replacer.cjs. Notethis relies on specifiers carrying explicit extensions (
config.js,utils/index.js), which is the norm under NodeNext.References
baseUrlmicrosoft/TypeScript#62207 (baseUrlremoval,"*"catch-all is the recommended replacement)baseUrlreports)