@rickosborne/rebound
Version:
Rick Osborne's utilities for working with bounded numbers
1,470 lines (929 loc) • 33 kB
Markdown
# @rickosborne/rebound
Tools for working with bounded numbers.
For example:
- RGB values: \[0,255\] for both integers and real numbers
- Hues: \[0,360), also int and real
- Chroma: \[0,1\]
- And other non-color-related things.
Built on top of:
- [@rickosborne/foundation](https://www.npmjs.com/package/@rickosborne/foundation) for data structures and general helpers
- [@rickosborne/guard](https://www.npmjs.com/package/@rickosborne/guard) for TypeScript guards
- [@rickosborne/typical](https://www.npmjs.com/package/@rickosborne/typical) for helper TypeScript type definitions
## Usage
Install via your favorite package manager.
Each package supports CommonJS `require`, ESM `import`, and TypeScript usage.
You also have a choice: barrel imports or direct imports.
Barrel imports mean you're going to require/import everything from the same package-level namespace:
```typescript
// CommonJS
const { isPlainObject, isListOf } = require("@rickosborne/guard");
// ESM / TypeScript
import { isPlainObject, isListOf } from "@rickosborne/guard";
```
Implications:
- Nice and simple.
- Your build system needs to do tree-shaking well ... or you'll end up adding the entire package even if you only import two functions.
The other option is to use direct imports:
```typescript
// CommonJS
const { isPlainObject } = require("@rickosborne/guard/is-object");
const { isListOf } = require("@rickosborne/guard/is-list-of");
// ESM / TypeScript
import { isPlainObject } from "@rickosborne/guard/is-object.js";
import { isListOf } from "@rickosborne/guard/is-list-of.js";
```
Implications:
- You (probably) don't have to worry about tree-shaking as your build (likely) ends up with only the functions you need.
If you're using a modern build system, there aren't any strong reasons to prefer one way over the other.
It's really just down to your personal preference.
### A quick note about file extensions
Do you need to use file extensions?
And if so, which extensions?
Honestly ... this is a dumpster fire question.
It really comes down to your own setup and configuration.
Within each package itself:
- The CommonJS files all have `.cjs` extensions.
- The ESM files all have `.mjs` extensions.
- Node subpath exports have been set up to send `.js` imports to the `.cjs` (via `require`) or `.mjs` (via `import`) files, depending on your setup.
So, in theory, the only extension which _won't_ work would be `.ts` because the source isn't included.
If you run into a problem with a particular configuration, file a GitHub issue with:
- Your `tsconfig.json`'s `module`, `moduleResolution`, and `target` settings.
- Your `package.json`'s `type` and `imports` settings.
- An example of another package which imports correctly for you.
## License
This package is licensed as [CC-BY-NC-SA-4.0] unless otherwise noted.
That is, Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.
[CC-BY-NC-SA-4.0]: https://creativecommons.org/licenses/by-nc-sa/4.0/
***
## API
### Classes
#### Bound
<a id="api-bound"></a>
```typescript
class Bound<T>
```
#### EmptyRange
<a id="api-emptyrange"></a>
```typescript
class EmptyRange extends RangeBase<never>
```
#### IntegerRange
<a id="api-integerrange"></a>
```typescript
class IntegerRange extends NumberRange
```
#### NumberRange
<a id="api-numberrange"></a>
```typescript
abstract class NumberRange extends RangeBase<number> implements CheckedBounds, RangeLike<number>
```
#### RangeBase
<a id="api-rangebase"></a>
```typescript
abstract class RangeBase<T> implements RangeLike<T>
```
#### RealRange
<a id="api-realrange"></a>
```typescript
class RealRange extends NumberRange
```
#### Rebound
<a id="api-rebound"></a>
```typescript
class Rebound<N extends number> implements TypedCheckedBounds
```
#### ReboundBuilder
<a id="api-reboundbuilder"></a>
```typescript
class ReboundBuilder<LowerInc extends LowerInEx, Lower extends number, Int extends NumberSet, Upper extends number, UpperInc extends UpperInEx>
```
#### StringRange
<a id="api-stringrange"></a>
```typescript
class StringRange extends RangeBase<string>
```
### Functions
#### addTypedProperties
<a id="api-addtypedproperties"></a>
```typescript
addTypedProperties: <T extends object, Bounds extends Omit<TypedCheckedBounds, "typeName">>(target: T, bounds: Bounds, typeName: string, fnName: string) => T & TypedCheckedBounds
```
#### assertBounded
<a id="api-assertbounded"></a>
```typescript
function assertBounded<N extends number, IfPresent extends boolean>(guard: If<IfPresent, GuardIfPresent<N>, GuardExact<N>>, errorProvider: OutOfBoundsErrorProvider, ifPresent: IfPresent, value: unknown, name?: string | undefined): asserts value is IfIfPresent<IfPresent, N>;
```
#### assertForBounds
<a id="api-assertforbounds"></a>
```typescript
function assertForBounds<N extends number, IfPresent extends boolean>(guard: If<IfPresent, GuardIfPresent<N>, GuardExact<N>>, errorProvider: OutOfBoundsErrorProvider, ifPresent: IfPresent, fnName?: string): If<IfPresent, AssertIfPresent<N>, AssertExact<N>>;
```
#### assertSameBounds
<a id="api-assertsamebounds"></a>
```typescript
function assertSameBounds(left: TypedCheckedBounds, right: TypedCheckedBounds, errorSupplier?: undefined | ((mismatchedKeys: (keyof TypedCheckedBounds)[], left: TypedCheckedBounds, right: TypedCheckedBounds) => Error)): void;
```
#### boundComparator
<a id="api-boundcomparator"></a>
```typescript
boundComparator: <T>(a: Bound<T> | Unbounded, b: Bound<T> | Unbounded) => number
```
#### boundedFromNumber
<a id="api-boundedfromnumber"></a>
```typescript
function boundedFromNumber<N extends number, IfPresent extends boolean>(guard: GuardExact<N>, errorProvider: OutOfBoundsErrorProvider, ifPresent: IfPresent, value: number | undefined | null, name?: string | undefined): If<IfPresent, N | undefined, N>;
```
#### boundedIntFromNumber
<a id="api-boundedintfromnumber"></a>
```typescript
function boundedIntFromNumber<N extends number, IsLowerInc extends boolean, Lower extends number, Upper extends number, IsUpperInc extends boolean, IfPresent extends boolean>(isLowerInc: IsLowerInc, lower: Lower, upper: Upper, isUpperInc: IsUpperInc, ifPresent: IfPresent, errorProvider: OutOfBoundsErrorProvider, strategy: ToInt<N>, value: number | undefined | null, name?: string | undefined): If<IfPresent, N | undefined, N>;
```
#### checkMissing
<a id="api-checkmissing"></a>
```typescript
function checkMissing<Lower extends number, LowerInc extends LowerInEx, Int extends NumberSet, UpperInc extends UpperInEx, Upper extends number>(config: Partial<BoundsConfig<LowerInEx, number, NumberSet, number, UpperInEx>>): asserts config is BoundsConfig<LowerInc, Lower, Int, Upper, UpperInc>;
```
#### effectiveRange
<a id="api-effectiverange"></a>
```typescript
effectiveRange: (bounds: CheckedBounds) => number
```
Calculate the effective range for a given bounds. That is, take into account the inclusivity of the lower and upper bounds.
#### fromNumberForBounds
<a id="api-fromnumberforbounds"></a>
```typescript
function fromNumberForBounds<N extends number, IfPresent extends boolean>(guard: GuardExact<N>, errorProvider: OutOfBoundsErrorProvider, ifPresent: IfPresent, fnName?: string): If<IfPresent, FromNumberIfPresent<N>, FromNumber<N>>;
```
#### guardForBounds
<a id="api-guardforbounds"></a>
```typescript
function guardForBounds<Bounds extends Omit<TypedCheckedBounds, "typeName">, N extends number, IfPresent extends boolean>(bounds: Bounds, typeName: string, fnName: string, ifPresent: IfPresent): If<IfPresent, GuardIfPresent<N>, GuardExact<N>>;
```
Generate a guard for the branded number type matching the given spec.
#### ifIfPresent
<a id="api-ififpresent"></a>
```typescript
ifIfPresent: <IfPresent extends boolean, T, U>(ifPresent: IfPresent, t: T, u: U) => If<IfPresent, T, U>
```
#### int255From01
<a id="api-int255from01"></a>
```typescript
function int255From01(value: Real01): Int255;
```
Convert a [Real01](#api-real01) to an [Int255](#api-int255).
#### int255From01
<a id="api-int255from01"></a>
```typescript
function int255From01(value: undefined): undefined;
```
#### integerFrom
<a id="api-integerfrom"></a>
```typescript
function integerFrom<N extends number, IsLowerInc extends boolean, Lower extends number, Upper extends number, IsUpperInc extends boolean, IfPresent extends boolean>(typeName: string, bounds: CheckedBoundsConfig<IsLowerInc, Lower, boolean, Upper, IsUpperInc> & {
label: string;
}, errorProvider: OutOfBoundsErrorProvider, ifPresent: IfPresent, strategy?: IntStrategy, fnName?: string): If<IfPresent, ConvertIfPresentTo<N>, ConvertTo<N>>;
```
#### integerGenerator
<a id="api-integergenerator"></a>
```typescript
function integerGenerator<N extends number>(bounds: CheckedBounds, options?: IntegerGeneratorOptions): Generator<N, undefined, undefined>;
```
#### randomBounded
<a id="api-randombounded"></a>
```typescript
randomBounded: <N extends number>(typeName: string, label: string, isLowerInc: boolean, lower: number, isInt: boolean, upper: number, isUpperInc: boolean, rng?: ({
float01(): number;
range(low: number, high: number): number;
}), fnName?: string) => RandomBounded<N>
```
#### rangeFromChecked
<a id="api-rangefromchecked"></a>
```typescript
rangeFromChecked: <Config extends CheckedBounds>(config: CheckedBounds) => BoundsLabel<DefinedFromCheckedConfig<Config>>
```
#### rangeFromConfig
<a id="api-rangefromconfig"></a>
```typescript
rangeFromConfig: <LowerInc extends LowerInEx, Lower extends number, Int extends NumberSet, Upper extends number, UpperInc extends UpperInEx, Config extends BoundsConfig<LowerInc, Lower, Int, Upper, UpperInc>>(config: Config) => BoundsLabel<Config>
```
#### real01From255
<a id="api-real01from255"></a>
```typescript
function real01From255(value: number | Int255 | Real255): Real01;
```
Convert a [Real255](#api-real255) or [Int255](#api-int255) to a [Real01](#api-real01).
#### real01From255
<a id="api-real01from255"></a>
```typescript
function real01From255(value: undefined): undefined;
```
#### real01From255
<a id="api-real01from255"></a>
```typescript
function real01From255(value: number | Int255 | Real255 | undefined): Real01 | undefined;
```
#### real255From01
<a id="api-real255from01"></a>
```typescript
real255From01: (value: Real01) => Real255
```
Convert a [Real01](#api-real01) to a [Real255](#api-real255).
#### sameBounds
<a id="api-samebounds"></a>
```typescript
sameBounds: (left: TypedCheckedBounds, right: TypedCheckedBounds) => boolean
```
#### scaleBounded
<a id="api-scalebounded"></a>
```typescript
scaleBounded: <Input extends number, Output extends number, IfPresent extends boolean>(inputBounds: TypedCheckedBounds, outputBounds: TypedCheckedBounds, ifPresent: IfPresent, fnName?: string) => If<IfPresent, ScaleIfPresent<Input, Output>, ScaleExact<Input, Output>>
```
#### validateBounded
<a id="api-validatebounded"></a>
```typescript
validateBounded: <IsLowerInc extends boolean, Lower extends number, IsInt extends boolean, Upper extends number, IsUpperInc extends boolean, IfPresent extends boolean>(isLowerInc: IsLowerInc, lower: Lower, isInt: IsInt, upper: Upper, isUpperInc: IsUpperInc, ifPresent: IfPresent, value: unknown) => value is IfIfPresent<IfPresent, number & ReboundedFromChecked<IsLowerInc, Lower, IsInt, Upper, IsUpperInc>>
```
### Interfaces
#### AnyBoundsConfig
<a id="api-anyboundsconfig"></a>
```typescript
export interface AnyBoundsConfig
```
#### AssertExact
<a id="api-assertexact"></a>
```typescript
export interface AssertExact<N extends number> extends TypedCheckedBounds
```
#### AssertIfPresent
<a id="api-assertifpresent"></a>
```typescript
export interface AssertIfPresent<N extends number> extends TypedCheckedBounds
```
#### BoundIsInclusive
<a id="api-boundisinclusive"></a>
```typescript
export interface BoundIsInclusive
```
#### BoundsConfig
<a id="api-boundsconfig"></a>
```typescript
export interface BoundsConfig<LowerInc extends LowerInEx, Lower extends number, Int extends NumberSet, Upper extends number, UpperInc extends UpperInEx> extends AnyBoundsConfig
```
#### BoundsWithRange
<a id="api-boundswithrange"></a>
```typescript
export interface BoundsWithRange<Range extends BoundsLabel<BoundsConfig<LowerInc, Lower, Int, Upper, UpperInc>>, LowerInc extends LowerInEx, Lower extends number, Int extends NumberSet, Upper extends number, UpperInc extends UpperInEx> extends BoundsConfig<LowerInc, Lower, Int, Upper, UpperInc>
```
#### CheckedBounds
<a id="api-checkedbounds"></a>
```typescript
export interface CheckedBounds
```
#### CheckedBoundsConfig
<a id="api-checkedboundsconfig"></a>
```typescript
export interface CheckedBoundsConfig<IsLowerInc extends boolean, Lower extends number, IsInt extends boolean, Upper extends number, IsUpperInc extends boolean>
```
#### ConvertIfPresentTo
<a id="api-convertifpresentto"></a>
```typescript
export interface ConvertIfPresentTo<N extends number> extends ConvertTo<N>
```
#### ConvertTo
<a id="api-convertto"></a>
```typescript
export interface ConvertTo<N extends number> extends TypedCheckedBounds
```
#### DefinedBounds
<a id="api-definedbounds"></a>
```typescript
export interface DefinedBounds
```
#### DefinedFromChecked
<a id="api-definedfromchecked"></a>
```typescript
export interface DefinedFromChecked<IsLowerInc extends boolean, Lower extends number, IsInt extends boolean, Upper extends number, IsUpperInc extends boolean> extends DefinedBounds
```
#### DefinedFromCheckedConfig
<a id="api-definedfromcheckedconfig"></a>
```typescript
export interface DefinedFromCheckedConfig<Config extends CheckedBounds> extends DefinedFromChecked<Config["isLowerInc"], Config["lower"], Config["isInt"], Config["upper"], Config["isUpperInc"]>
```
#### FromNumber
<a id="api-fromnumber"></a>
```typescript
export interface FromNumber<N extends number> extends TypedCheckedBounds
```
#### FromNumberIfPresent
<a id="api-fromnumberifpresent"></a>
```typescript
export interface FromNumberIfPresent<N extends number> extends FromNumber<N>
```
#### GuardExact
<a id="api-guardexact"></a>
```typescript
export interface GuardExact<T extends number> extends TypedCheckedBounds
```
#### GuardIfPresent
<a id="api-guardifpresent"></a>
```typescript
export interface GuardIfPresent<T extends number> extends TypedCheckedBounds
```
#### IntegerGeneratorOptions
<a id="api-integergeneratoroptions"></a>
```typescript
export interface IntegerGeneratorOptions
```
#### NumberSetIsInt
<a id="api-numbersetisint"></a>
```typescript
export interface NumberSetIsInt
```
#### RandomBounded
<a id="api-randombounded"></a>
```typescript
export interface RandomBounded<N extends number> extends TypedCheckedBounds
```
#### RangedBounds
<a id="api-rangedbounds"></a>
```typescript
export interface RangedBounds extends DefinedBounds
```
#### RangeLike
<a id="api-rangelike"></a>
```typescript
export interface RangeLike<T>
```
#### ReboundAllowUndef
<a id="api-reboundallowundef"></a>
```typescript
export interface ReboundAllowUndef
```
#### Rebounded
<a id="api-rebounded"></a>
```typescript
export interface Rebounded<Range extends BoundsLabel<BoundsConfig<LowerInc, Lower, Int, Upper, UpperInc>>, LowerInc extends LowerInEx, Lower extends number, Int extends NumberSet, Upper extends number, UpperInc extends UpperInEx>
```
Nice, short, human-readable signature which will show up in the IDE.
#### ReboundedFromChecked
<a id="api-reboundedfromchecked"></a>
```typescript
export interface ReboundedFromChecked<IsLowerInc extends boolean, Lower extends number, IsInt extends boolean, Upper extends number, IsUpperInc extends boolean> extends Rebounded<BoundsLabel<DefinedFromChecked<IsLowerInc, Lower, IsInt, Upper, IsUpperInc>>, LowerInExFrom<IsLowerInc>, Lower, NumberSetFrom<IsInt>, Upper, UpperInExFrom<IsUpperInc>>
```
#### ReboundedFromConfig
<a id="api-reboundedfromconfig"></a>
```typescript
export interface ReboundedFromConfig<LowerInc extends LowerInEx, Lower extends number, Int extends NumberSet, Upper extends number, UpperInc extends UpperInEx> extends Rebounded<BoundsLabel<BoundsConfig<LowerInc, Lower, Int, Upper, UpperInc>>, LowerInc, Lower, Int, Upper, UpperInc>
```
#### ReboundFnOptions
<a id="api-reboundfnoptions"></a>
```typescript
export interface ReboundFnOptions
```
#### ReboundRandomOptions
<a id="api-reboundrandomoptions"></a>
```typescript
export interface ReboundRandomOptions
```
#### ReboundToIntOptions
<a id="api-reboundtointoptions"></a>
```typescript
export interface ReboundToIntOptions extends ReboundFnOptions
```
#### ResolvedFnOptions
<a id="api-resolvedfnoptions"></a>
```typescript
export interface ResolvedFnOptions extends Required<ReboundFnOptions>
```
#### ResolvedToIntOptions
<a id="api-resolvedtointoptions"></a>
```typescript
export interface ResolvedToIntOptions extends Required<ReboundToIntOptions>
```
#### ScaleExact
<a id="api-scaleexact"></a>
```typescript
export interface ScaleExact<Input extends number, Output extends number> extends TypedCheckedBounds
```
#### ScaleIfPresent
<a id="api-scaleifpresent"></a>
```typescript
export interface ScaleIfPresent<Input extends number, Output extends number> extends TypedCheckedBounds
```
#### TypedBounds
<a id="api-typedbounds"></a>
```typescript
export interface TypedBounds extends RangedBounds
```
#### TypedCheckedBounds
<a id="api-typedcheckedbounds"></a>
```typescript
export interface TypedCheckedBounds extends CheckedBounds
```
### TypeAliases
#### BoundedNumber
<a id="api-boundednumber"></a>
```typescript
type BoundedNumber<Bounds> = Bounds extends BoundsConfig<infer LowerInc, infer Lower, infer Int, infer Upper, infer UpperInc> ? (number & ReboundedFromConfig<LowerInc, Lower, Int, Upper, UpperInc>) : Bounds extends CheckedBoundsConfig<infer IsLowerInc extends boolean, infer Lower extends number, infer IsInt extends boolean, infer Upper extends number, infer IsUpperInc extends boolean> ? (number & ReboundedFromChecked<IsLowerInc, Lower, IsInt, Upper, IsUpperInc>) : never;
```
Brand a number type with a type-generated explanation of its bounds, so that it can only accept other numbers with the exact same bounds.
#### BoundsLabel
<a id="api-boundslabel"></a>
```typescript
type BoundsLabel<C extends DefinedBounds> = `${C extends {
lowerInc: infer LowerInc extends LowerInEx;
} ? LowerInc : never}${C extends {
lower: NegInfinity;
} ? NegInfinityLabel : C extends {
lower: infer Lower extends number;
} ? number extends Lower ? never : `${Lower}` : never}${C extends {
int: infer Int extends NumberSet;
} ? Int extends IntegerSet ? ".." : "," : never}${C extends {
upper: PosInfinity;
} ? PosInfinityLabel : C extends {
upper: infer Upper extends number;
} ? number extends Upper ? never : `${Upper}` : never}${C extends {
upperInc: infer UpperInc extends UpperInEx;
} ? UpperInc : never}`;
```
#### BoundType
<a id="api-boundtype"></a>
```typescript
type BoundType = typeof BOUND_GT | typeof BOUND_GTE | typeof BOUND_LT | typeof BOUND_LTE;
```
#### If
<a id="api-if"></a>
```typescript
type If<IfPresent extends boolean | undefined, T, U> = IfPresent extends true ? T : U;
```
#### IfIfPresent
<a id="api-ififpresent"></a>
```typescript
type IfIfPresent<IfPresent extends boolean, T> = IfPresent extends true ? (T | null | undefined) : T;
```
#### InfinityBound
<a id="api-infinitybound"></a>
```typescript
type InfinityBound = number & {
infinity: string;
};
```
#### Int255
<a id="api-int255"></a>
```typescript
type Int255 = typeof int255.numberType;
```
An integer in the range [0,255].
#### Int360
<a id="api-int360"></a>
```typescript
type Int360 = typeof int360.numberType;
```
An integer in the range [0,360).
#### IntegerSet
<a id="api-integerset"></a>
```typescript
type IntegerSet = "int";
```
#### IntStrategy
<a id="api-intstrategy"></a>
```typescript
type IntStrategy = typeof ROUND | typeof CEIL | typeof TRUNC | typeof FLOOR | ((value: number) => number);
```
#### IsBounded
<a id="api-isbounded"></a>
```typescript
type IsBounded<N extends number> = N extends {
[BOUNDS]: object;
} ? true : false;
```
Helper for checking if you're dealing with a [BoundedNumber](#api-boundednumber).
#### IsFinite
<a id="api-isfinite"></a>
```typescript
type IsFinite<N extends number> = N extends {
[BOUNDS]: {
lower: infer Lower extends number;
upper: infer Upper extends number;
};
} ? Lower extends InfinityBound ? false : Upper extends InfinityBound ? false : true : never;
```
Whether the number has defined bounds (neither upper nor lower is infinite).
#### IsInclusive
<a id="api-isinclusive"></a>
```typescript
type IsInclusive<Inc extends UpperInEx | LowerInEx> = BoundIsInclusive[Inc];
```
#### IsInfinite
<a id="api-isinfinite"></a>
```typescript
type IsInfinite<N extends number> = N extends {
[BOUNDS]: {
lower: infer Lower extends number;
upper: infer Upper extends number;
};
} ? Lower extends InfinityBound ? true : Upper extends InfinityBound ? true : false : never;
```
Whether the number has infinite bounds, either upper or lower.
#### IsIntegersOnly
<a id="api-isintegersonly"></a>
```typescript
type IsIntegersOnly<N extends number> = N extends {
[BOUNDS]: {
int: IntegerSet;
};
} ? true : false;
```
Extract whether the number only accepts integers.
#### IsIntFrom
<a id="api-isintfrom"></a>
```typescript
type IsIntFrom<Int extends NumberSet> = NumberSetIsInt[Int];
```
#### LowerBound
<a id="api-lowerbound"></a>
```typescript
type LowerBound<N extends number> = N extends {
[BOUNDS]: {
lower: infer Lower extends number;
};
} ? Lower : never;
```
Extract the value for the lower bound.
#### LowerBoundIsInc
<a id="api-lowerboundisinc"></a>
```typescript
type LowerBoundIsInc<N extends number> = N extends {
[BOUNDS]: {
lowerInc: infer LowerInc extends LowerInEx;
};
} ? LowerInc extends LowerInclusive ? true : false : never;
```
Extract whether the lower bound is inclusive (true) or exclusive (false).
#### LowerExclusive
<a id="api-lowerexclusive"></a>
```typescript
type LowerExclusive = "(";
```
#### LowerInclusive
<a id="api-lowerinclusive"></a>
```typescript
type LowerInclusive = "[";
```
#### LowerInEx
<a id="api-lowerinex"></a>
```typescript
type LowerInEx = LowerInclusive | LowerExclusive;
```
#### LowerInExFrom
<a id="api-lowerinexfrom"></a>
```typescript
type LowerInExFrom<B extends boolean> = boolean extends B ? never : true extends B ? LowerInclusive : LowerExclusive;
```
#### NegInfinity
<a id="api-neginfinity"></a>
```typescript
type NegInfinity = number & {
infinity: NegInfinityLabel;
};
```
#### NegInfinityLabel
<a id="api-neginfinitylabel"></a>
```typescript
type NegInfinityLabel = "-∞";
```
#### NumberSet
<a id="api-numberset"></a>
```typescript
type NumberSet = IntegerSet | RealSet;
```
#### NumberSetFrom
<a id="api-numbersetfrom"></a>
```typescript
type NumberSetFrom<B extends boolean> = boolean extends B ? never : true extends B ? IntegerSet : RealSet;
```
#### OutOfBoundsErrorProvider
<a id="api-outofboundserrorprovider"></a>
```typescript
type OutOfBoundsErrorProvider = (value: unknown, name?: string | undefined) => Error;
```
#### PosInfinity
<a id="api-posinfinity"></a>
```typescript
type PosInfinity = number & {
infinity: PosInfinityLabel;
};
```
#### PosInfinityLabel
<a id="api-posinfinitylabel"></a>
```typescript
type PosInfinityLabel = "+∞";
```
#### Real01
<a id="api-real01"></a>
```typescript
type Real01 = typeof real01.numberType;
```
A real number in the range [0,1].
#### Real255
<a id="api-real255"></a>
```typescript
type Real255 = typeof real255.numberType;
```
A real number in the range [0,255].
#### Real360
<a id="api-real360"></a>
```typescript
type Real360 = typeof real360.numberType;
```
A number in the range [0,360).
#### RealSet
<a id="api-realset"></a>
```typescript
type RealSet = "real";
```
#### ReboundConfigBuilder
<a id="api-reboundconfigbuilder"></a>
```typescript
type ReboundConfigBuilder<LowerInc extends LowerInEx, Lower extends number, Int extends NumberSet, Upper extends number, UpperInc extends UpperInEx> = {
readonly config: BoundsConfig<LowerInc, Lower, Int, Upper, UpperInc>;
} & IsCompleteConfig<LowerInc, Lower, Int, Upper, UpperInc> extends true ? {
build(): Rebound<BoundedNumber<BoundsConfig<LowerInc, Lower, Int, Upper, UpperInc>>>;
} : ((number extends Lower ? {
fromExclusive<L extends number>(value: L): ReboundConfigBuilder<LowerExclusive, L, Int, Upper, UpperInc>;
fromInclusive<L extends number>(value: L): ReboundConfigBuilder<LowerInclusive, L, Int, Upper, UpperInc>;
fromNegInfinity(): ReboundConfigBuilder<LowerInExFrom<true>, NegInfinity, Int, Upper, UpperInc>;
fromValue<L extends number, LI extends boolean>(value: L, inclusive: LI): ReboundConfigBuilder<LowerInExFrom<LI>, L, Int, Upper, UpperInc>;
} : object) & (NumberSet extends Int ? {
intOnly<IR extends boolean>(int: IR): ReboundConfigBuilder<LowerInc, Lower, NumberSetFrom<IR>, Upper, UpperInc>;
integers(): ReboundConfigBuilder<LowerInc, Lower, IntegerSet, Upper, UpperInc>;
reals(): ReboundConfigBuilder<LowerInc, Lower, RealSet, Upper, UpperInc>;
} : object) & (number extends Upper ? {
toExclusive<U extends number>(value: U): ReboundConfigBuilder<LowerInc, Lower, Int, U, UpperExclusive>;
toInclusive<U extends number>(value: U): ReboundConfigBuilder<LowerInc, Lower, Int, U, UpperInclusive>;
toPosInfinity(): ReboundConfigBuilder<LowerInc, Lower, Int, PosInfinity, UpperInExFrom<true>>;
toValue<U extends number, UI extends boolean>(value: U, inclusive: UI): ReboundConfigBuilder<LowerInc, Lower, Int, U, UpperInExFrom<UI>>;
} : object));
```
#### ToInt
<a id="api-toint"></a>
```typescript
type ToInt<N> = (this: void, value: number, name?: string | undefined) => N;
```
#### Unbound
<a id="api-unbound"></a>
```typescript
type Unbound<N extends number> = IsBounded<N> extends true ? number : N;
```
You could also just cast to `number`, but this provides a nice explicit and hard-to-miss visual. It is also helpful in downstream type definitions where you need the bound types to be fungible.
#### Unbounded
<a id="api-unbounded"></a>
```typescript
type Unbounded = typeof unbounded;
```
#### UpperBound
<a id="api-upperbound"></a>
```typescript
type UpperBound<N extends number> = N extends {
[BOUNDS]: {
upper: infer Upper extends number;
};
} ? Upper : never;
```
Extract the value for the upper bound.
#### UpperBoundIsInc
<a id="api-upperboundisinc"></a>
```typescript
type UpperBoundIsInc<N extends number> = N extends {
[BOUNDS]: {
upperInc: infer UpperInc extends UpperInEx;
};
} ? UpperInc extends UpperInclusive ? true : false : never;
```
Extract whether the lower bound is inclusive (true) or exclusive (false).
#### UpperExclusive
<a id="api-upperexclusive"></a>
```typescript
type UpperExclusive = ")";
```
#### UpperInclusive
<a id="api-upperinclusive"></a>
```typescript
type UpperInclusive = "]";
```
#### UpperInEx
<a id="api-upperinex"></a>
```typescript
type UpperInEx = UpperInclusive | UpperExclusive;
```
#### UpperInExFrom
<a id="api-upperinexfrom"></a>
```typescript
type UpperInExFrom<B extends boolean> = boolean extends B ? never : true extends B ? UpperInclusive : UpperExclusive;
```
### Variables
#### assertInt255
<a id="api-assertint255"></a>
```typescript
assertInt255: import("./assert-bounded.js").AssertExact<never>
```
#### assertInt360
<a id="api-assertint360"></a>
```typescript
assertInt360: import("./assert-bounded.js").AssertExact<never>
```
#### assertReal01
<a id="api-assertreal01"></a>
```typescript
assertReal01: import("./assert-bounded.js").AssertExact<never>
```
#### assertReal255
<a id="api-assertreal255"></a>
```typescript
assertReal255: import("./assert-bounded.js").AssertExact<never>
```
#### assertReal360
<a id="api-assertreal360"></a>
```typescript
assertReal360: import("./assert-bounded.js").AssertExact<never>
```
#### BOUND_GT
<a id="api-bound-gt"></a>
```typescript
BOUND_GT = ">"
```
#### BOUND_GTE
<a id="api-bound-gte"></a>
```typescript
BOUND_GTE = ">="
```
#### BOUND_LT
<a id="api-bound-lt"></a>
```typescript
BOUND_LT = "<"
```
#### BOUND_LTE
<a id="api-bound-lte"></a>
```typescript
BOUND_LTE = "<="
```
#### BOUND_TYPES
<a id="api-bound-types"></a>
```typescript
BOUND_TYPES: Readonly<BoundType[]>
```
#### BOUNDS
<a id="api-bounds"></a>
```typescript
BOUNDS: unique symbol
```
#### boundTypeComparator
<a id="api-boundtypecomparator"></a>
```typescript
boundTypeComparator: Comparator<BoundType>
```
#### boundTypeComparisonIsValid
<a id="api-boundtypecomparisonisvalid"></a>
```typescript
boundTypeComparisonIsValid: Readonly<Record<BoundType, (comparison: number) => boolean>>
```
#### CEIL
<a id="api-ceil"></a>
```typescript
CEIL = "ceil"
```
#### FLOOR
<a id="api-floor"></a>
```typescript
FLOOR = "floor"
```
#### INT_SET
<a id="api-int-set"></a>
```typescript
INT_SET: IntegerSet
```
#### int255
<a id="api-int255"></a>
```typescript
int255: Rebound<number & import("./spec.js").ReboundedFromConfig<"[", 0, "int", 255, "]">>
```
#### int360
<a id="api-int360"></a>
```typescript
int360: Rebound<number & import("./spec.js").ReboundedFromConfig<"[", 0, "int", 359, "]">>
```
#### isInt255
<a id="api-isint255"></a>
```typescript
isInt255: import("./guard-bounded.js").GuardExact<number & import("./spec.js").ReboundedFromConfig<"[", 0, "int", 255, "]">>
```
#### isInt360
<a id="api-isint360"></a>
```typescript
isInt360: import("./guard-bounded.js").GuardExact<number & import("./spec.js").ReboundedFromConfig<"[", 0, "int", 359, "]">>
```
#### isReal01
<a id="api-isreal01"></a>
```typescript
isReal01: import("./guard-bounded.js").GuardExact<number & import("./spec.js").ReboundedFromConfig<"[", 0, "real", 1, "]">>
```
#### isReal255
<a id="api-isreal255"></a>
```typescript
isReal255: import("./guard-bounded.js").GuardExact<number & import("./spec.js").ReboundedFromConfig<"[", 0, "real", 255, "]">>
```
#### isReal360
<a id="api-isreal360"></a>
```typescript
isReal360: import("./guard-bounded.js").GuardExact<number & import("./spec.js").ReboundedFromConfig<"[", 0, "real", 360, ")">>
```
#### LOWER_EX
<a id="api-lower-ex"></a>
```typescript
LOWER_EX: LowerExclusive
```
#### LOWER_IN
<a id="api-lower-in"></a>
```typescript
LOWER_IN: LowerInclusive
```
#### REAL_SET
<a id="api-real-set"></a>
```typescript
REAL_SET: RealSet
```
#### real01
<a id="api-real01"></a>
```typescript
real01: Rebound<number & import("./spec.js").ReboundedFromConfig<"[", 0, "real", 1, "]">>
```
#### real255
<a id="api-real255"></a>
```typescript
real255: Rebound<number & import("./spec.js").ReboundedFromConfig<"[", 0, "real", 255, "]">>
```
#### real360
<a id="api-real360"></a>
```typescript
real360: Rebound<number & import("./spec.js").ReboundedFromConfig<"[", 0, "real", 360, ")">>
```
#### ROUND
<a id="api-round"></a>
```typescript
ROUND = "round"
```
#### toInt255
<a id="api-toint255"></a>
```typescript
toInt255: import("./from-number-bounded.js").FromNumberIfPresent<number & import("./spec.js").ReboundedFromConfig<"[", 0, "int", 255, "]">>
```
#### toInt360
<a id="api-toint360"></a>
```typescript
toInt360: import("./from-number-bounded.js").FromNumberIfPresent<number & import("./spec.js").ReboundedFromConfig<"[", 0, "int", 359, "]">>
```
#### toReal01
<a id="api-toreal01"></a>
```typescript
toReal01: import("./from-number-bounded.js").FromNumberIfPresent<number & import("./spec.js").ReboundedFromConfig<"[", 0, "real", 1, "]">>
```
#### toReal255
<a id="api-toreal255"></a>
```typescript
toReal255: import("./from-number-bounded.js").FromNumberIfPresent<number & import("./spec.js").ReboundedFromConfig<"[", 0, "real", 255, "]">>
```
#### toReal360
<a id="api-toreal360"></a>
```typescript
toReal360: import("./from-number-bounded.js").FromNumberIfPresent<number & import("./spec.js").ReboundedFromConfig<"[", 0, "real", 360, ")">>
```
#### TRUNC
<a id="api-trunc"></a>
```typescript
TRUNC = "trunc"
```
#### TYPED_BOUNDS_KEYS
<a id="api-typed-bounds-keys"></a>
```typescript
TYPED_BOUNDS_KEYS: (keyof TypedBounds)[]
```
#### TYPED_CHECKED_BOUNDS_KEYS
<a id="api-typed-checked-bounds-keys"></a>
```typescript
TYPED_CHECKED_BOUNDS_KEYS: (keyof TypedCheckedBounds)[]
```
#### unbounded
<a id="api-unbounded"></a>
```typescript
unbounded: unique symbol
```
#### UPPER_EX
<a id="api-upper-ex"></a>
```typescript
UPPER_EX: UpperExclusive
```
#### UPPER_IN
<a id="api-upper-in"></a>
```typescript
UPPER_IN: UpperInclusive
```