How I organize my Typescript types.
Typescript gives you the following options to organize your interfaces and types:
- Ambient typing. Ie. Global
*.d.ts
files can let you use types without aneed forimport
statements. The types are made available recursively in all subdirectories, and these files can be distributed throughout your project. - You can store interfaces directly on the main file that use them.
- Like any other class, function or object, you can explicitly
export
andimport
types from.ts
files. Maybe these are TS files that contain nothing but types. These can be kept in the root folder or locally in the specific directory.
It’s good to remember that software development is an art and not a science. I’m no longer a fan of the kind of ultra-precise, foolproof software engineering that cathedral-builders vouch for. Software engineering != engineering, software engineering == organized logic and it’s more important to have a great developer experience than to have a foolproof codebase.
I’ve found that options #1 and #2 are ergonomic and sensible options for projects of all sizes. See the following files from the DevCollective project to get an idea for what I’m talking about:
Example of #1: https://github.com/Mintbean/DevCollective.io/blob/2a9fc9855d5b29bb45e31237095a0fb0d1b05b5f/database.d.ts
Example of #2: https://github.com/Mintbean/DevCollective.io/blob/2a9fc9855d5b29bb45e31237095a0fb0d1b05b5f/src/service/EmailService.ts
I never use #3 anymore. I tried it and the experiment failed miserably. It leads to overcomplications and overengineering… the imports all need to be managed, the types+interfaces look exactly like runtime objects in your editor, and the explosion of tokens becomes ridiculously difficult for your meat-brain to process. And Typescript infers types even if they haven’t been imported explicitly in your current file — So there’s no real need to import/export EVERY SINGLE type.
So, I prefer using #1 and #2 in projects of all sizes.