# @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
```

