ts-dependent-types
An experimental collection of dependent type definitions in TypeScript
Dependent types are types that rely on the value of variables rather than only on types. These can be useful to further restrict contracts.
For example:
Given a function that retries and operation, we want to limit the number of retries to a range of 1 to 5
TypeScript supports a limited number of members for a single union and a limited recursion depth, so these types have some limitations if used multiple times in conjunction. This is also the reasoning for some of the provided ranges of numbers. One of the changes for TypeScript 4.6.1 will allow to change this limit.
Usage
import { Range } from "ts-dependent-types";
const logNumberInRange = (value: Range<0, 10>) => console.log(value);
type TwoDigitHexadecimal = `${HexadecimalDigit}${HexadecimalDigit}`; // "00" | "01" | .. | "FF"
const x64AssemblyCallInstruction: TwoDigitHexadecimal = "FF";
Exports
Numbers
Increment
Increment
takes a number in the range of -24 to 24 and produces a literal of the following number
type Five = Increment<4>; // 5
IncrementUnsigned
IncrementUnsigned
takes a number in the range of 0 to 48 and produces a literal of the following number
type FourtyEight = IncrementUnsigned<47>; // 48
Decrement
Decrement
takes a number in the range of -24 to 24 and produces a literal of the previous number
type Three = Decrement<4>; // 3
DecrementUnsigned
DecrementUnsigned
takes a number in the range of 0 to 48 and produces a literal of the previous number
type FourtySix = Decrement<47>; // 46
Digit
A type corresponding to the range of 0
to 9
Range
Represents a union of number literals between two numbers, supports -24
to 24
const logNumberInRange = (value: Range<0, 10>) => console.log(value);
logNumberInRange(9);
logNumberInRange(10);
logNumberInRange(11); // this will error
type SupportedRange = Range<-24, 24>; // -24 | -23 | ... | 24
type UnsupportedRange = Range<0, 100>; // this will error
RangeUnsigned
Represents a union of number literals between two numbers, supports 0
to 48
const logNumberInRange = (value: RangeUnsigned<30, 48>) => console.log(value);
logNumberInRange(35);
logNumberInRange(40);
logNumberInRange(11); // this will error
type SupportedRange = RangeUnsigned<0, 48>; // 0 | 1 | ... | 48
type UnsupportedRange = RangeUnsigned<0, 100>; // this will error
NextPowerOf2
Represents 2^(T+1) (up to 2^48)
type SomePowerOf2 = NextPowerOf2<4>; // 8
PowerOf2Range
Represents a union of powers of 2 up to 2^T (0 < T < 49)
type FourPowersOf2 = PowerOf2Range<4>; // 2 | 4 | 8 | 16
type SupportedPowersOf2 = PowerOf2Range; // 2 | 4 | ... | 281474976710656
Strings
Character
A type corresponding to any printable ASCII character
HexadecimalDigit
type TwoDigitHexadecimal = `${HexadecimalDigit}${HexadecimalDigit}`; // "00" | "01" | .. | "FF"
UppercaseLetter
Any uppercase ASCII letter
LowercaseLetter
Any lowercase ASCII letter
Letter
Any ASCII letter
SpecialCharacter
Any printable special ASCII character
NextUppercaseLetter
Increment
takes a Letter
and produces the follwing letter
type B = NextUppercaseLetter<'A'>; // "B"
PreviousUppercaseLetter
Increment
takes an UppercaseLetter
and produces the previous letter
type A = PreviousUppercaseLetter<'B'>; // "A"
NextLowercaseLetter
Increment
takes a LowercaseLetter
and produces the previous letter
type LowercaseB = NextLowercaseLetter<'a'>; // "b"
PreviousLowercaseLetter
Increment
takes an UppercaseLetter
and produces the previous letter
type LowercaseA = PreviousLowercaseLetter<'b'>; // "a"
UppercaseLetterRange
Produces a range of UppercaseLetter
s between two given UppercaseLetter
s
type AtoD = UppercaseLetterRange<'A', 'D'>; // "A" | "B" | "C" | "D"
LowercaseLetterRange
Produces a range of LowercaseLetter
s between two given LowercaseLetter
s
type LowercaseAtoD = LowercaseLetterRange<'a', 'd'>; // "a" | "b" | "c" | "d"
Prior Art
(TODO: add links and examples)