Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/akhansari/ts-adt
Algebraic Data Types & Typescript
https://github.com/akhansari/ts-adt
adt algebraic-data-types typescript
Last synced: 2 months ago
JSON representation
Algebraic Data Types & Typescript
- Host: GitHub
- URL: https://github.com/akhansari/ts-adt
- Owner: akhansari
- Created: 2024-03-11T17:34:22.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-09-10T16:12:43.000Z (4 months ago)
- Last Synced: 2024-09-10T18:06:30.948Z (4 months ago)
- Topics: adt, algebraic-data-types, typescript
- Language: TypeScript
- Homepage:
- Size: 47.9 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# Algebraic Data Types & Typescript
Algebraic data types are a way of representing data by **combining** simple types using algebraic operations.
There are two main kinds of algebraic types: product types and sum types. Discriminated unions are a specific implementation of sum types.## Product types (AND types)
Product types represent a combination of types.
```typescript
type Shirt = {
size: string
sleeveLength: string
shape: string
}
```## Sum types (OR types)
Sum types represent a choice between types.
```typescript
type ShirtSize = "S" | "M" | "L" | "XL" | "XXL"
type SleeveLength = "Short" | "Long"
```## Compose
Compose small types from other small types.
```typescript
type SleeveLength = "Short" | "Long"type Shirt = {
size: "S" | "M" | "L" | "XL" | "XXL"
sleeveLength: SleeveLength
shape: string
}
```## Pattern Matching
It's possible by adding a "kind" field to the product type.
```typescript
type SleeveLength = "Short" | "Long"type Shirt = {
kind: "Shirt"
size: "S" | "M" | "L" | "XL" | "XXL"
sleeveLength: SleeveLength
shape: string
}type Jean = {
kind: "Jean"
hipSize: number
legSize: number
...
}type Clothing = Shirt | Jean
const clothing: Clothing = {
kind: "Shirt",
size: "L",
sleeveLength: "Short",
shape: "Straight",
}const describeClothing = (clothing: Clothing) => {
switch (clothing.kind) {
case "Shirt": return "This is a shirt!"
case "Jean": return "This is a jean!"
}
}
```You can go further by adding sections to kinds in order to combine Clothing and Shoes.
- `kind: "Clothing/Shirt"`
- `kind: "Clothing/Jean"`
- `kind: "Shoes/Sneakers"`
- `kind: "Shoes/Boots"````typescript
type Product = {
id: number
price: Price
item: Clothing | Shoes
}
```## OpenAPI
In OpenAPI specification, sum types are represented by `oneOf`.
```yaml
Clothing:
oneOf:
- $ref: "#/components/schemas/Shirt"
- $ref: "#/components/schemas/Jean"
discriminator:
propertyName: kind
mapping:
Shirt: "#/components/schemas/Shirt"
Jean: "#/components/schemas/Jean"
```