Skip to content

tsc --watch 7.x does not detect edits to files under a symlinked directory inside the project (6.0.3 did) #64448

Description

🔎 Search Terms

"tsc --watch symlink", "watch mode symlinked directory not detected", "walkDir symlink", "7.0 watch symlink", "fswatch symlink"

🕗 Version & Regression Information

⏯ Playground Link

Not applicable (watch mode / file system behaviour). Standalone repro below, no external dependencies.

💻 Code

Layout: a shared package whose src directory is symlinked into the app's src tree, a common pattern for shared code in monorepos.

repro/
  pkg-common/src/types.ts
  app/tsconfig.json
  app/src/index.ts
  app/src/common -> ../../pkg-common/src   (symlink)
// pkg-common/src/types.ts
export type Greeting = { message: string };
// app/src/index.ts
import { Greeting } from './common/types';

const g: Greeting = { message: 'hi' };
console.log(g.message);
// app/tsconfig.json
{
  "compilerOptions": { "target": "es2022", "module": "nodenext", "strict": true, "outDir": "dist", "types": [] },
  "include": ["src/**/*.ts"]
}

Steps:

mkdir -p repro/pkg-common/src repro/app/src && cd repro
# create the three files above, then:
ln -s ../../pkg-common/src app/src/common
cd app && npx -p [email protected] tsc --watch --pretty false -p tsconfig.json
# in another terminal, each of these should trigger "File change detected":
echo '// edit' >> ../pkg-common/src/types.ts      # real path      -> nothing happens
echo '// edit' >> src/common/types.ts             # via symlink    -> nothing happens
echo '// edit' >> src/index.ts                    # regular file   -> recompiles

🙁 Actual behavior

With TypeScript 7.0.2 (and @next), tsc --watch compiles the symlinked file on the initial build but never notices later edits to it, whether the edit is made through the real path or through the symlink path. Nothing is printed and no recompilation happens; introducing a type error in types.ts is not reported until the watcher is restarted. Edits to src/index.ts (not behind a symlink) are detected within a second.

Results on macOS 26.6.2 (arm64), node 22.22.0, 20 s wait per edit:

Edit tsc 6.0.3 tsc 7.0.2 7.1.0-dev.20260925.1
pkg-common/src/types.ts (real path) detected not detected not detected
app/src/common/types.ts (via symlink) detected not detected not detected
app/src/index.ts (regular file) detected detected detected

In a real project with three shared packages symlinked into src/ (about 1,800 files behind symlinks), this means every edit in those packages is silently ignored by the watcher, so tsc --watch cannot be used as the dev loop there.

🙂 Expected behavior

Edits to files that are part of the program should trigger a recompilation regardless of whether the file is reached through a symlinked directory, as in 6.0.3. If following symlinks during the directory walk is intentionally avoided, the watcher could still subscribe to the real directory of each program file that resolves through a symlink (6.x watched realpaths for this reason).

Additional information about the issue

  • Only macOS was tested.
  • preserveSymlinks is not set (default false), so the program already knows the realpath of these files.
  • Happy to test a fix or provide more details.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Needs InvestigationThis issue needs a team member to investigate its status.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions