Entities
This project and documentation are work in progress
Example code: src/lib/entities
Entities are where we encode the types in our system. You might call these 'models' or 'domain objects'. We also store types related to entities, such as the objects used to create / update them.
It's time for our first proper look at the example code. Open the entities folder and you'll see encodings for all the types required by our example system - a system for a "community library", with users, books and loans:
Let's dive right into the Book type:
There's a lot going on here. Let's break the code down:
What is io-ts and all this t.type business?
IO-TS is a library for defining types that can be verified at runtime, which it calls 'codecs'. You can derive TypeScript types from them too, meaning that you can now 'prove' your TypeScript types are an accurate representation of the data being received.
Naturally, this makes your project much more robust, because you know real-world data won't sneak past your type system
Codecs are pretty easy to write and map quite transparently to TypeScript types.
For instance, if you have a codec like this:
You can derive a typescript static type:
But you can also derive a runtime check. Here I'm using a util $cast
that's defined in my project:
You can find the $cast
helper in cast.ts
Whenever you see a function beginning with a dollar in this project, it signifies a higher-order function that itself returns a function.
For instance, a function named $foo
will itself return another function called foo
. You don't have to use this convention, but I find it makes HOFs a little easier to spot and reason about.
Check out the io-ts-types project for some very helpful extra types, like UUID or timezoned dates.
Do I have to use io-ts? What if I just want to use plain JS?
Not at all - you can use plain TypeScript types
and interfaces
if you prefer. That said, being able to validate your types is a huge boost to your ability to clamp down on bugs and unpredictable behaviour, so I'd recommend giving it a go. There are also libraries like joi you can use.
If you're using plain JS and don't care about validation, you might just write types in JSDoc or even skip the entities folder entirely (though this will make working with operations a little harder, as the types will be less obvious).
Back to the book types
Now we know what IO-TS does, we can deconstruct the Book.ts
module:
There's a Book, which obviously encodes a book a user can borrow
There's a BookInput, which is used during Book CRUD
There are casts for both of the above 'codecs'
There are static types derived from both codecs
The index.ts file
At the root of the entities folder should be an index.ts
file that exports all the static types and casts defined within each module. This will itself then be exported at the library root so that adapters and bindings can import domain types.
Last updated