Inherit a Node repo? Open Programming TypeScript at chapter 11
The book has thirteen chapters, but three of them and two appendices are the parts you can use straight away on a client site.
In brief
- For an FDE, chapter 11 on interoperating with JavaScript is where to open the book first
- Appendices D and F turn adding types to legacy code into small, safe steps
- Chapters 12 and 8 help you debug Node services running on the client's servers
Boris Cherny’s Programming TypeScript has 13 chapters and 7 appendices. But an FDE who has just been given access to a client’s Node repo does not need to start on page one: chapters 8, 11 and 12, together with Appendices D and F, are the parts closest to the job of reading and fixing that code.
The book is published by O’Reilly, came out around May 2019 and carries the subtitle Making Your JavaScript Applications Scale. It is aimed at intermediate JavaScript developers. It covers frontend and backend, along with how to migrate an existing JavaScript project to TypeScript and run it in production.
Those words, “an existing project”, are the reason an FDE should read it. On a client site you rarely start from scratch. What you inherit is usually a Node service written in plain JavaScript, a few outdated libraries and a deadline that rules out a rewrite.
Open the book at chapter 11, not chapter 1
Chapter 11, “Interoperating with JavaScript”, teaches migration from JavaScript to TypeScript one step at a time: it begins with adding TSC and ends with turning on strict mode. That order matches how an FDE should work in someone else’s repo.
Imagine a client hands you a Node service of about 40 JavaScript files, and you need to fix the webhook handling flow that lives in three of them. Do not migrate all 40 files.
Add TSC so it checks the existing code, then convert only the three files you have to touch. A small diff is one the client’s engineers can review, and you get correct types where the risk is highest.
What to do in your first session: run TSC on the repo without changing a single line of code. The resulting list of errors is a map of where the code relies on hidden assumptions.
What about libraries with no types?
The rest of chapter 11 deals with third-party JavaScript libraries in three cases. If a library ships its own type declarations, use them. If the declarations are on DefinitelyTyped, install them. The last case, with no declarations at all, is where the time goes.
Imagine the client has an internal npm package written years ago that exports via module.exports. Nobody outside the company has ever written types for it. Appendix D, “Recipes for Writing Declaration Files for Third-Party JavaScript Modules”, has recipes for exactly the CommonJS and UMD export styles that older Node code tends to use.
What to do: sort every dependency into those three groups on day one. The third group tells you how many hours you will spend writing declaration files, and that is the number to give the client before you promise a delivery date.
Tighten types flag by flag, not in one switch
Appendix F, “TSC Compiler Flags for Safety”, lists the compiler flags that make code safer. On a client codebase its value lies in letting you tighten gradually, rather than switching on strict mode at once and getting hundreds of errors.
Suppose enabling one flag surfaces 120 errors. A pull request that fixes 120 places will make the client’s reviewers reluctant to approve it. Enable one flag at a time, one PR per flag, each PR covering a single class of error, and the client’s team understands what you are doing and can carry on after you leave.
When errors blow up on the client’s server
Chapter 12 has a dedicated section, “Running TypeScript on the Server”, along with source maps, project references and error monitoring. When a compiled service throws in production, the stack trace points at the generated JavaScript file. Source maps take you back to the exact line of TypeScript, so you can read the client’s logs without guessing.
Chapter 8 fills in what is missing for Node code: callbacks, Promises, async/await, event emitters and type-safe multithreading with child processes. Legacy client services often mix callbacks with Promises, and typing those asynchronous boundaries is the quickest way to find where errors are being swallowed.
What to do: before fixing your first bug, check whether the client’s build emits source maps and whether errors are sent to any monitoring tool.
Two common mistakes from doing things in the wrong order
The first mistake is turning on strict mode in the first session. Chapter 11 puts strict last for a reason: enabling it on a JavaScript repo that has never had types turns a three-file fix into a giant PR that nobody on the client side wants to review.
The second mistake is renaming the whole repo to .ts before sorting dependencies into the three groups. Imagine converting all 40 files and only then discovering that the internal package has no type declarations. Every call site errors, and you have to stop halfway to write declaration files following Appendix D.
The way to avoid both is in the book: classify libraries first, write declarations for the third group, then convert files and enable flags one by one following Appendix F.
Who should read it, and in what order
The book suits people who write solid JavaScript but have never brought TypeScript into an existing codebase. Suggested order: chapter 11, Appendix D, Appendix F, chapter 12, then chapter 8.
Open the early chapters on the type system when you hit a concept you are unsure of. The book came out in 2019, so check details about tooling and compiler flags against the current TypeScript documentation.
Reading is not enough. Boris Cherny has an official GitHub repo of exercise answers, bcherny/programming-typescript-answers, so you can work the exercises yourself and compare. A better exercise still is to migrate an open-source Node repo gradually, following the exact sequence of chapter 11.
For your career, this skill is easy to prove. A CV line such as “incrementally migrated a Node service from JavaScript to TypeScript, enabled strict mode across a series of PRs, wrote type declarations for internal CommonJS modules” is far more persuasive than “knows TypeScript”.
Imagine an FDE job posting saying the candidate will write code directly in the client’s existing systems, on a Node and TypeScript stack. That is a signal the employer needs someone who can change legacy code safely, and the CV line above answers exactly that; put it at the top of your experience section, with a link to the repo you migrated yourself.
Read the table of contents with an FDE’s eye, and those three chapters and two appendices are the part written for people who have to fix someone else’s code without breaking it.
Was this article useful?
Thanks for the feedback!