Skip to content

Composite projects: support strict dependencies #36743

@alexeagle

Description

@alexeagle

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions