https://github.com/hazae41/integers
Statically typed integer arithmetic (experimental)
https://github.com/hazae41/integers
arithmetic compile-time integers numbers typed typescript
Last synced: about 1 month ago
JSON representation
Statically typed integer arithmetic (experimental)
- Host: GitHub
- URL: https://github.com/hazae41/integers
- Owner: hazae41
- Created: 2023-05-10T15:19:28.000Z (almost 2 years ago)
- Default Branch: master
- Last Pushed: 2023-05-10T15:37:59.000Z (almost 2 years ago)
- Last Synced: 2024-10-18T16:17:59.669Z (6 months ago)
- Topics: arithmetic, compile-time, integers, numbers, typed, typescript
- Language: TypeScript
- Homepage:
- Size: 2.23 MB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
Awesome Lists containing this project
README
# Integers
Statically typed integer arithmetic (experimental)
```tsx
type X = Add<32_000, 32_123> // 64_123type Y = Subtract // 123
type P = IsGreater<1_001, 1_000> // true
``````tsx
const x: 64_123 = add(32_000, 32_123)const y: 123 = subtract(x, 64_000)
const p: true = greater(1_001, 1_000)
```## Summary
It can type check numbers fast, up to 2**16 (=65_536), but the compiler will sometimes yell at you, especially when both the left-hand and right-hand sides are generic
## Benefits and drawbacks
- Fast type checking
- Add and subtract big numbers up to 2**16 (= 65_536) (it can be increased but bundling will be slower)
- Boolean inequalities
- Slow bundling (~10 seconds)
- The compiler will sometimes yell at you## Inequalities
Several ways to attempt inequalities type checking, unfortunately none of them are ready for production
### Nevering
- Fast type checking
- You need to have the left-hand side type to compare
- The compiler will sometimes yell at you```tsx
export type Greater =
IsGreater extends true ? X : neverexport type Less =
IsLess extends true ? X : neverexport type GreaterOrEquals =
IsGreaterOrEquals extends true ? X : neverexport type LessOrEquals =
IsLessOrEquals extends true ? X : neverfunction increment(x: GreaterOrEquals) {
return add(x, 1)
}increment(150) // 151
```### Remapping
- Elegant, you can just use `Greater<100>` to only accept numbers `>100`
- Painfully slowwwwwwww type checking even on expensive computer```tsx
export type Greater = Exclude extends true ? P : never]: never }, string | symbol>export type GreaterOrEquals = Exclude extends true ? P : never]: never }, string | symbol>
export type Less = Exclude extends true ? P : never]: never }, string | symbol>
export type LessOrEquals = Exclude extends true ? P : never]: never }, string | symbol>
export type Range = Exclude extends true ? P : never]: never }, string | symbol>
function increment(x: X & Greater<100>) {
return add(x, 1)
}const x = increment(150) // Greater<101>
```### Opaque type guarding
- This is annoying to use
- This doesn't solve anything
- You still have to do runtime if-else branching```tsx
export type Greater = number & { __greater: T }export type Less = number & { __less: T }
export type Range = Greater & Less
export function greater(x: number, y: Y): x is Greater {
return x > y as any
}export function less(x: number, y: Y): x is Less {
return x < y as any
}export function greaterOrEquals(x: number, y: Y): x is GreaterOrEquals {
return x >= y as any
}export function lessOrEquals(x: number, y: Y): x is LessOrEquals {
return x <= y as any
}function increment(x: Greater<100>) {
return add(x, 1)
}const x = 150
if (greater(x, 100))
increment(x) // number
```