Leverage TypeScript project references
Initial checklist
- [x] I read the support docs
- [x] I read the contributing guide
- [x] I agree to follow the code of conduct
- [x] I searched issues and couldn’t find anything (or linked relevant results below)
- [x] If applicable, I’ve added docs and tests
Description of changes
This changes the TypeScript configuration of the project. It’s based on https://github.com/orgs/unifiedjs/discussions/238. The project now uses 2 TypeScript configurations: tsconfig.json and tsconfig.build.json. There’s also tsconfig.base.json. This is an implementation detail, it only exists so it can be extended from.
tsconfig.build.json is used to build the source files.
- It only includes the
libdirectory. - It emits the type declarations into the
typesdirectory. - It does not include the
nodetypes, meaning that importing Node.js builtins will cause the build to fail. - It includes the
domlib, which is needed because of an upstream dependency. - It does not allow the use of JSX.
- It includes a new file
lib/exports.ts, which can be used to re-export additional types. This replaces the oldindex.jsin the project root, which@typedeftags to mimic type exports.
tsconfig.json is used to typecheck the rest of the project.
- It excludes the
libdirectory. - It does not emit type declarations.
- It includes the
nodetypes, meaning we can import Node.js builtins (such asnode:test) - It does not include the
domtypes, meaning we can’t use browser globals there. - It builds
tsconfig.build.jsonfirst, based onreferences. - It type checks the
typesdirectory emitted bytsconfig.build.json. We have run into JSDoc specific emit issues before, so this is really nice to have.
To build or rebuild the project, we can now run either tsc --build or tsc --build --force. This correctly uses incremental builds, so a second run of tsc --build is faster.
Without this PR, after building, we have type errors in our editor. This is now solved.
Variations of this are possible. The main point is:
- Separate JavaScript source files from other JavaScript files.
- Use separate configurations for different environments/purposes. This is even more apparent for mono repos that target different conflicting environments. (I have a commit ready for https://github.com/mdx-js/mdx, but wanted to discuss this in a simpler repo first.)
- Use
rootDirandoutDir. - Avoid writing
.d.tsfiles. - Use
.tsfiles to write TypeScript things that are not possible with types in JSDoc.
An interesting idea that builds on this, is to move type definitions from @typedef tags into TypeScript files.