UNPKG

@rickosborne/rebound

Version:

Rick Osborne's utilities for working with bounded numbers

1,470 lines (929 loc) 33 kB
# @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 ```