https://github.com/polatengin/andorra
A TypeScript utility to tag and differentiate ID fields across data models, ensuring type-safe usage and preventing mismatches in large projects.
https://github.com/polatengin/andorra
data-model extends interface type type-safety typescript
Last synced: 10 months ago
JSON representation
A TypeScript utility to tag and differentiate ID fields across data models, ensuring type-safe usage and preventing mismatches in large projects.
- Host: GitHub
- URL: https://github.com/polatengin/andorra
- Owner: polatengin
- Created: 2022-02-04T19:28:22.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2022-02-05T19:16:25.000Z (about 4 years ago)
- Last Synced: 2025-02-11T13:47:53.184Z (12 months ago)
- Topics: data-model, extends, interface, type, type-safety, typescript
- Language: TypeScript
- Homepage:
- Size: 1.95 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Andorra
In large projects, we usually have way more than one data model.
Except very rare situations, in every data model, we have an ID field.
For example;
```typescript
export interface User {
id: number;
name: string;
email: string;
password: string;
}
export interface Product {
id: number;
name: string;
price: number;
description: string;
}
```
If a function returns a `User` or `Product`, we can use the `ID` to find the data in the database.
That means, seperate functions can be used to find a `User` or `Product` by their `ID`s.
But, what if a developer pass `ID` of a product to a function that expects an `ID` of a `User`?
More generally, how can we differentiate `ID` of a `User` from `ID` of a `Product`?
In the [index.ts](./index.ts) file, we have a type to differentiate `ID` fields of different data models.
```typescript
type ID = T & { __id: Tag };
```
Basically, we `tag` different `ID` fields and make sure the expected `ID` field is tagged with the correct `tag`.
```typescript
type UserId = ID;
type ProductId = ID;
```
In the below example, we have seperate functions that return `User` and `Product` objects, from different `ID`s.
```typescript
const getUser = (id: UserId) => {
return {
id,
name: 'Engin Polat 🧑💻',
};
};
const getProduct = (id: ProductId) => {
return {
id,
name: 'Surface Book 3 Pro 💻',
};
};
```
We can call these functions ONLY by passing correct `ID` to them.
```typescript
getUser(5 as UserId);
const userId = 5 as UserId;
getUser(userId);
```
Either it should be a `UserId` or a `number` that explicitely casted to `UserId`.
```typescript
getProduct(8 as ProductId);
const productId = 8 as ProductId;
getProduct(productId);
```
It's the same with `ProductId` field in the above example.
Good part is, it's not possible to call `getUser` with a `ProductId` or `getProduct` with a `UserId`.
```typescript
// We can't even compile the below code
getUser(productId);
getProduct(userId);
```