microsoft / microsoft/TypeScript
Composite projects: support strict dependencies
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
Google (and Bazel rules_typescript) use a special-purpose TypeScript compiler. One of the reasons for this is we want to enforce strict dependencies.
Strict dependencies means you may only import or reference symbols declared in a project you explicitly declare to be an input. This is an essential property in a large monorepo as a defense against accidental coupling between projects.
For example we might have three directories, A B and C:
alexeagle@alexeagle:~/Projects/repro_strict_deps$ cat A/a.ts
export const a = 'hello';
alexeagle@alexeagle:~/Projects/repro_strict_deps$ cat A/tsconfig.json
{
"compilerOptions": {
"composite": true
}
}
alexeagle@alexeagle:~/Projects/repro_strict_deps$ cat B/b.ts
import {a} from '../A/a';
export function sayHello(f: string) {
console.log(a + f);
}
alexeagle@alexeagle:~/Projects/repro_strict_deps$ cat B/tsconfig.json
{
"compilerOptions": {
"composite": true,
},
"references": [
{"path": "../A"}
]
}
alexeagle@alexeagle:~/Projects/repro_strict_deps$ cat C/c.ts
import {a} from '../A/a'; // SHOULD FAIL HERE
import {sayHello} from '../B/b';
sayHello('world');
console.error(a);
alexeagle@alexeagle:~/Projects/repro_strict_deps$ cat C/tsconfig.json
{
"references": [
// NO REF TO A
{"path": "../B"}
]
}
Let's say we work on library B. We decide we no longer need to depend on A, so we remove the dependency, but this breaks users such as C. This is a serious impediment to good code practices because our dependency on A leaked to users who reference its symbols without declaring their own dependency. In a big monorepo, the breakage of removing a dependency can prevent ever cleaning them up
We would like to propose a strictness setting when used with Project References, such that imports (or ambient references) from transitive dependencies should be disallowed.
/cc @evmar @josephperrott
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the A/a.ts, B/b.ts, and C/c.ts example with their tsconfig.json project references. Read the current composite-project and project-reference behavior, then define how a strictness setting should reject C's direct import from A while allowing its declared dependency on B. Done means the transitive import or ambient reference is diagnosed when no direct reference is declared.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100