Project References

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

Professional TypeScript Masterclass Lessons

1.Introduction
free
⏱️ 1:54
2.Setup
free
⏱️ 5:44
3.Primitive Types
free
⏱️ 1:42
4.Instance Types
free
⏱️ 1:52
5.Arrays And Tuples
free
⏱️ 1:38
6.Objects
free
⏱️ 1:33
7.const declarations
free
⏱️ 1:03
8.Function Types
free
⏱️ 1:57
9.Structural Typing
free
⏱️ 2:10
10.Classes in TypeScript
free
⏱️ 1:48
11.Target Compiler Option
free
⏱️ 2:37
12.Generics
⏱️ 3:02
13.Special Types any And unknown
⏱️ 2:00
14.JavaScript to TypeScript
⏱️ 1:32
15.Frontend Projects
⏱️ 3:49
16.Type Assertions
⏱️ 2:15
17.Type Casting
⏱️ 1:16
18.Modules
⏱️ 1:55
19.Type Declarations
⏱️ 4:25
20.Creating NPM packages
⏱️ 3:20
21.Async Await
⏱️ 3:05
22.Running in NodeJS
⏱️ 1:40
23.Lexical this
⏱️ 2:34
24.readonly Modifier
⏱️ 1:59
25.Union Types
⏱️ 2:57
26.Literal Types
⏱️ 2:58
27.Type Narrowing
⏱️ 4:19
28.Discriminated Unions
⏱️ 3:29
29.Class Parameter Properties
⏱️ 1:02
30.Strict Compiler Option
⏱️ 6:18
31.null vs undefined
⏱️ 4:19
32.Intersection Types
⏱️ 2:03
33.Optional Modifier
⏱️ 2:47
34.Non Null Assertion Operator
⏱️ 3:40
35.Interfaces
⏱️ 2:28
36.Interface Declaration Merging
⏱️ 1:01
37.Types vs Interfaces
⏱️ 2:16
38.never Type
⏱️ 3:00
39.implements Keyword
⏱️ 1:25
40.Definite Assignment Assertion
⏱️ 2:31
41.User Defined Type Guards
⏱️ 2:02
42.Assertion Functions
⏱️ 3:42
43.Function Overloading
⏱️ 4:15
44.Call Signatures
⏱️ 2:53
45.Abstract Classes
⏱️ 1:53
46.Index Signatures
⏱️ 3:08
47.Readonly Arrays and Tuples
⏱️ 2:58
48.Double Assertions
⏱️ 2:20
49.const Assertions
⏱️ 3:55
50.this Parameter
⏱️ 2:33
51.Generic Constraints
⏱️ 2:43
52.typeof Type Operator
⏱️ 2:12
53.Lookup Types
⏱️ 3:12
54.keyof Type Operator
⏱️ 3:55
55.Conditional Types
⏱️ 4:39
56.Contitional Types with Unions and never
⏱️ 3:32
57.infer Keyword and `ReturnType<T>`
⏱️ 3:47
58.Mapped Types
⏱️ 2:48
59.Mapped Type Modifiers
⏱️ 3:37
60.Template Literal Type
⏱️ 4:28
61.Partial<T>
⏱️ 1:27
62.Required<T>
⏱️ 1:36
63.Readonly<T>
⏱️ 1:34
64.Record<K, T>
⏱️ 4:05
65.Project References
⏱️ 4:18
66.undefined vs. optional
⏱️ 2:48
67.satisfies Operator
⏱️ 2:42
68.PropertyKey Type
⏱️ 0:57
69.ThisType<T>
⏱️ 4:11
70.Awaited<T>
⏱️ 4:12
71.String Manipulation Types
⏱️ 3:36
72.Mapped Types as Clauses
⏱️ 4:01
73.Union vs Intersection Mental Model
⏱️ 3:36
74.Enums are Bad
⏱️ 8:11

Project References

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

Project On GitHub

Sample

example-lib code:

export function hello() {
return 'Hello fam!';
}

example-app code:

async function main() {
console.log(hello());
}

main();

Composite

Allow the example-lib to be used as a reference, by adding to the tsconfig.json:

{
"compilerOptions": {
"declaration": true, // recommended
"declarationMap": true, // recommended
"rootDir": "src", // recommended

"composite": true
}
}

References

Add projects as references to example-app in the tsconfig.json:

{
"references": [{ "path": "../example-lib/" }]
}

Consume the Reference

You can now consume the reference by directing the import to the project reference folder e.g.:

import { hello } from '../../example-lib';

async function main() {
console.log(hello());
}

main();

Building

Use the -b (or --build) flag to build the example-app project including anything it references e.g. you can add to your package.json:

{
"scripts" {
"build": "tsc --build .",
"start": "npm run build -- --watch"
}
}

During dev:

cd example-app
npm start

On the build server:

cd example-app
npm run build

Running

Run the generated JavaScript 🫰🏻

node example-app/lib/index.js
javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

Project references allow you to safely and reliably work on multiple TypeScript projects at the same time. So in this lesson, we will look at the use case for project references along with the features that enable them, such as the composite property, the references property, and the compiler bill flag. So let's go to demonstrate project references. We have two simple projects, an example Lib, which is going to be our referenced project. And then we have the Consumer Example app, which is going to be referencing the Lib project. Within our example Lib, we have a very simple function called Hello

00:32

that simply returns the string. And the use case is to use this or any other utility library functions within our app. For example, Hey, we have a very simple main function that logs out the value that will be returned from this Hello Utility. Now of course, right now type sheet is complaining that this Hello function does not exist within the example app. And one potential bad fix would be to start importing example a Lib source code into our example app. Now you probably don't want to do this intuitively either. And Touch Script is also going to complain in this particular case.

01:04

And the error is that the source code from example Lib, does not exist within the root directory that is specified for the example app project. Now you can try to fix this by modifying the include of your app project to include the source code of the lip project, but that results in more issues. For example, now your app code is also a part of the lip code within a particular TS config. So you can actually end up importing your app code into your lip code projects. So the better solution is to actually use project references with project references.

01:36

App and Lib are still going to be in their own self-contained projects. And the only dependency that we will create is that the lib code can be imported into the app code. The first modification that we will need to make is within the Ts config of the project that we want to reference. That is the project that we want to use like a library. So within our example Lib, we need to modify the TS config compiler options and set composite to true. This option makes sure that this project is now ready to be referenced by other projects and ensures that there are certain options

02:08

that are enabled within this particular TS config, such as declarations being generated and a decent root TIR for this particular project. Congratulations. And now our example, lib is ready for consumption. So we jump into our example app. And now in order to add a reference to any other project that we want to use with an example app, we add a references section to the TS config and add the path to as many projects as we want to reference. And we are only referencing example lib over here. With this change in place, we can now import the example lib into our example app

02:42

as if it was an NPM package. We have to use a relative path because we haven't published it to NPM, but notice that we are including the route directory that contains the package of Jason, for example, lib. And now because of that project reference text script is able to resolve the hello function from that Route directory. And that's it for the Ts config changes. Basically add composite to anything that you want to reference and add references to anything that does the consumption. Now there is one more neat trick within TypeScript for the projects that are doing the consuming and that is the build flag.

03:15

Instead of using the minus P or project flag, use the build flag. And this will not only compile this particular project, but any of the projects that it depends upon. So it'll compile in type check example app as well as example lib. And we can see this in action by opening up the terminal and executing in PM run Built. And we can see that the output is not only generated for example app, but also for the example the project. And this automatic building of any of the dependencies not only works for static bills, but also for the incremental watch flag.

03:48

So within the example app package of Jason, we have another script called Start, which executes build with an additional minus minus watch flag. And when we execute that, if you modify the source code for the example, lib the project build, for example, app will automatically pick up that a dependent project has been modified and actually recompile that. And if you open up another terminal and execute our example app, you can see that it is now using the updated example, lib generated JavaScript.

Professional TypeScript Masterclass

Professional TypeScript Masterclass

1.Introduction
free
⏱️ 1:54
2.Setup
free
⏱️ 5:44
3.Primitive Types
free
⏱️ 1:42
4.Instance Types
free
⏱️ 1:52
5.Arrays And Tuples
free
⏱️ 1:38
6.Objects
free
⏱️ 1:33
7.const declarations
free
⏱️ 1:03
8.Function Types
free
⏱️ 1:57
9.Structural Typing
free
⏱️ 2:10
10.Classes in TypeScript
free
⏱️ 1:48
11.Target Compiler Option
free
⏱️ 2:37
12.Generics
⏱️ 3:02
13.Special Types any And unknown
⏱️ 2:00
14.JavaScript to TypeScript
⏱️ 1:32
15.Frontend Projects
⏱️ 3:49
16.Type Assertions
⏱️ 2:15
17.Type Casting
⏱️ 1:16
18.Modules
⏱️ 1:55
19.Type Declarations
⏱️ 4:25
20.Creating NPM packages
⏱️ 3:20
21.Async Await
⏱️ 3:05
22.Running in NodeJS
⏱️ 1:40
23.Lexical this
⏱️ 2:34
24.readonly Modifier
⏱️ 1:59
25.Union Types
⏱️ 2:57
26.Literal Types
⏱️ 2:58
27.Type Narrowing
⏱️ 4:19
28.Discriminated Unions
⏱️ 3:29
29.Class Parameter Properties
⏱️ 1:02
30.Strict Compiler Option
⏱️ 6:18
31.null vs undefined
⏱️ 4:19
32.Intersection Types
⏱️ 2:03
33.Optional Modifier
⏱️ 2:47
34.Non Null Assertion Operator
⏱️ 3:40
35.Interfaces
⏱️ 2:28
36.Interface Declaration Merging
⏱️ 1:01
37.Types vs Interfaces
⏱️ 2:16
38.never Type
⏱️ 3:00
39.implements Keyword
⏱️ 1:25
40.Definite Assignment Assertion
⏱️ 2:31
41.User Defined Type Guards
⏱️ 2:02
42.Assertion Functions
⏱️ 3:42
43.Function Overloading
⏱️ 4:15
44.Call Signatures
⏱️ 2:53
45.Abstract Classes
⏱️ 1:53
46.Index Signatures
⏱️ 3:08
47.Readonly Arrays and Tuples
⏱️ 2:58
48.Double Assertions
⏱️ 2:20
49.const Assertions
⏱️ 3:55
50.this Parameter
⏱️ 2:33
51.Generic Constraints
⏱️ 2:43
52.typeof Type Operator
⏱️ 2:12
53.Lookup Types
⏱️ 3:12
54.keyof Type Operator
⏱️ 3:55
55.Conditional Types
⏱️ 4:39
56.Contitional Types with Unions and never
⏱️ 3:32
57.infer Keyword and `ReturnType<T>`
⏱️ 3:47
58.Mapped Types
⏱️ 2:48
59.Mapped Type Modifiers
⏱️ 3:37
60.Template Literal Type
⏱️ 4:28
61.Partial<T>
⏱️ 1:27
62.Required<T>
⏱️ 1:36
63.Readonly<T>
⏱️ 1:34
64.Record<K, T>
⏱️ 4:05
65.Project References
⏱️ 4:18
66.undefined vs. optional
⏱️ 2:48
67.satisfies Operator
⏱️ 2:42
68.PropertyKey Type
⏱️ 0:57
69.ThisType<T>
⏱️ 4:11
70.Awaited<T>
⏱️ 4:12
71.String Manipulation Types
⏱️ 3:36
72.Mapped Types as Clauses
⏱️ 4:01
73.Union vs Intersection Mental Model
⏱️ 3:36
74.Enums are Bad
⏱️ 8:11